GestoreCredenzialiEngine.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.pdd.core.credenziali.engine;

  21. import java.security.cert.CertStore;
  22. import java.util.List;
  23. import java.util.Map;

  24. import org.apache.commons.lang.StringUtils;
  25. import org.openspcoop2.core.config.constants.TipoAutenticazionePrincipal;
  26. import org.openspcoop2.core.constants.Costanti;
  27. import org.openspcoop2.core.id.IDSoggetto;
  28. import org.openspcoop2.message.OpenSPCoop2Message;
  29. import org.openspcoop2.message.utils.WWWAuthenticateErrorCode;
  30. import org.openspcoop2.message.utils.WWWAuthenticateGenerator;
  31. import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
  32. import org.openspcoop2.pdd.core.autenticazione.WWWAuthenticateConfig;
  33. import org.openspcoop2.pdd.core.connettori.InfoConnettoreIngresso;
  34. import org.openspcoop2.pdd.core.credenziali.Credenziali;
  35. import org.openspcoop2.pdd.core.credenziali.GestoreCredenzialiConfigurationException;
  36. import org.openspcoop2.pdd.core.credenziali.GestoreCredenzialiException;
  37. import org.openspcoop2.pdd.core.keystore.GestoreKeystoreCaching;
  38. import org.openspcoop2.pdd.logger.OpenSPCoop2Logger;
  39. import org.openspcoop2.protocol.engine.SecurityTokenUtilities;
  40. import org.openspcoop2.protocol.sdk.ChannelSecurityToken;
  41. import org.openspcoop2.protocol.sdk.Context;
  42. import org.openspcoop2.protocol.sdk.SecurityToken;
  43. import org.openspcoop2.protocol.sdk.constants.IntegrationFunctionError;
  44. import org.openspcoop2.protocol.sdk.state.RequestInfo;
  45. import org.openspcoop2.security.keystore.cache.GestoreOCSPResource;
  46. import org.openspcoop2.security.keystore.cache.GestoreOCSPValidator;
  47. import org.openspcoop2.utils.LoggerBuffer;
  48. import org.openspcoop2.utils.certificate.Certificate;
  49. import org.openspcoop2.utils.certificate.CertificateDecodeConfig;
  50. import org.openspcoop2.utils.certificate.CertificateUtils;
  51. import org.openspcoop2.utils.certificate.KeyStore;
  52. import org.openspcoop2.utils.certificate.PrincipalType;
  53. import org.openspcoop2.utils.transport.TransportUtils;
  54. import org.openspcoop2.utils.transport.http.IOCSPValidator;

  55. /**    
  56.  * GestoreCredenzialiEngine
  57.  *
  58.  * @author Poli Andrea (poli@link.it)
  59.  * @author $Author$
  60.  * @version $Rev$, $Date$
  61.  */
  62. public class GestoreCredenzialiEngine {

  63.     private static final String KEYWORD_GATEWAY_CREDENZIALI = "@@GatewayCredenziali@@";
  64.     public static String getDBValuePrefixGatewayCredenziali(String identitaGateway, String credenzialiFornite) {
  65.         return KEYWORD_GATEWAY_CREDENZIALI+identitaGateway+"@@"+credenzialiFornite;
  66.     }
  67.     public static boolean containsPrefixGatewayCredenziali(String value) {
  68.         return value.startsWith(GestoreCredenzialiEngine.KEYWORD_GATEWAY_CREDENZIALI);
  69.     }
  70.     public static String erasePrefixGatewayCredenziali(String value) {
  71.         if(value.startsWith(GestoreCredenzialiEngine.KEYWORD_GATEWAY_CREDENZIALI)) {
  72.             String s = value.substring(GestoreCredenzialiEngine.KEYWORD_GATEWAY_CREDENZIALI.length());
  73.             if(s.contains("@@")) {
  74.                 s = s.substring(s.indexOf("@@")+2);
  75.             }
  76.             return s;
  77.         }
  78.         else {
  79.             return value;
  80.         }
  81.     }
  82.     public static String readIdentitaGatewayCredenziali(String value) {
  83.         if(value.startsWith(GestoreCredenzialiEngine.KEYWORD_GATEWAY_CREDENZIALI)) {
  84.             String s = value.substring(GestoreCredenzialiEngine.KEYWORD_GATEWAY_CREDENZIALI.length());
  85.             if(s.contains("@@")) {
  86.                 return s.substring(0,s.indexOf("@@"));
  87.             }
  88.             else {
  89.                 return null;
  90.             }
  91.         }
  92.         else {
  93.             return null;
  94.         }
  95.     }
  96.    
  97.     private String identita = null;
  98.     private boolean portaApplicativa = false;
  99.     private Context context;
  100.     private RequestInfo requestInfo;
  101.     public GestoreCredenzialiEngine(boolean portaApplicativa, Context context){
  102.         this.portaApplicativa = portaApplicativa;
  103.         this.context = context;
  104.         if(this.context!=null && this.context.containsKey(Costanti.REQUEST_INFO)) {
  105.             this.requestInfo = (RequestInfo) this.context.get(Costanti.REQUEST_INFO);
  106.         }
  107.     }

  108.     private String getPrefixMessaggioAutenticazioneFallita(String auth) {
  109.         return "Autenticazione "+auth+" del Gestore delle Credenziali '"+this.identita+ "' fallita, ";
  110.     }
  111.     private static final String NESSUN_TIPO_CREDENZIALI_TRASPORTO = "nessun tipo di credenziali (basic/ssl/principal) riscontrate nel trasporto";
  112.     private static final String CREDENZIALI_PRESENTI_TRASPORTO = "credenziali presenti nel trasporto ";
  113.    
  114.     private String getConfigurazioneNonValidaPrefix(ModalitaAutenticazioneGestoreCredenziali modalita) {
  115.         return "Configurazione del Gestore delle Credenziali non valida, con la modalità '"+modalita.getValore()+"' ";
  116.     }
  117.     private String getConfigurazioneNonValidaHeaderNonDefiniti(ModalitaAutenticazioneGestoreCredenziali modalita, String auth) {
  118.         return getConfigurazioneNonValidaPrefix(modalita)+"devono essere definiti gli header http su cui veicolare le credenziali "+auth;
  119.     }
  120.     private String getConfigurazioneNonValidaHeaderNonDefinito(ModalitaAutenticazioneGestoreCredenziali modalita, String auth) {
  121.         return getConfigurazioneNonValidaPrefix(modalita)+"deve essere definito un header http su cui veicolare le credenziali "+auth;
  122.     }
  123.     private String getConfigurazioneNonValidaAlmenoHeaderDefinito(ModalitaAutenticazioneGestoreCredenziali modalita, String auth) {
  124.         return getConfigurazioneNonValidaPrefix(modalita)+"deve essere definito almeno un header http su cui veicolare le credenziali "+auth;
  125.     }    
  126.    
  127.     private String getMessaggioHeaderHttpNonPresente(String headerName) {
  128.         return "Header HTTP '"+headerName+"' non presente";
  129.     }
  130.    
  131.     private String getSuffixNonValido(Exception e) {
  132.         return " non valido: "+e.getMessage();
  133.     }
  134.    
  135.     private String getMessaggioCertificatoPresenteHeaderNonValido(String headerName, Exception t) {
  136.         return "Certificato presente nell'header '"+headerName+"' non valido: "+t.getMessage();
  137.     }
  138.    
  139.     public Credenziali elaborazioneCredenziali(
  140.             IDSoggetto idSoggetto,
  141.             InfoConnettoreIngresso infoConnettoreIngresso, OpenSPCoop2Message messaggio)
  142.             throws GestoreCredenzialiException,
  143.             GestoreCredenzialiConfigurationException {
  144.        
  145.         if(messaggio!=null) {
  146.             // non usato
  147.         }
  148.        
  149.         Map<String, List<String>> headerTrasporto = infoConnettoreIngresso.getUrlProtocolContext().getHeaders();
  150.        
  151.         Credenziali credenzialiTrasporto = infoConnettoreIngresso.getCredenziali();
  152.        
  153.         GestoreCredenzialiConfigurazione configurazione = GestoreCredenzialiConfigurazione.getConfigurazione(!this.portaApplicativa, idSoggetto);
  154.        
  155.         // Abilitato ?
  156.         boolean enabled = (configurazione!=null) && configurazione.isEnabled();
  157.         if(!enabled) {
  158.             return credenzialiTrasporto; // credenziali originali
  159.         }
  160.        
  161.         // Identita' Gateway
  162.         this.identita=configurazione.getNome();
  163.        
  164.         // Realm
  165.        
  166.         String realm = configurazione.getRealm();
  167.         String authType = configurazione.getAuthType();
  168.        
  169.        
  170.         // AutenticazioneGateway

  171.         TipoAutenticazioneGestoreCredenziali autenticazioneGateway = configurazione.getTipoAutenticazioneCanale();
  172.         if(autenticazioneGateway==null){
  173.             throw new GestoreCredenzialiException("Tipo di autenticazione per il gestore delle credenziali non definito");
  174.         }
  175.         if(TipoAutenticazioneGestoreCredenziali.BASIC.equals(autenticazioneGateway)){
  176.             String usernameGateway = configurazione.getAutenticazioneCanaleBasicUsername();
  177.             String passwordGateway = configurazione.getAutenticazioneCanaleBasicPassword();
  178.             if(usernameGateway == null){
  179.                 throw new GestoreCredenzialiException("Richiesta autenticazione basic del gestore delle credenziali, ma username non definito");
  180.             }
  181.             if(passwordGateway == null){
  182.                 throw new GestoreCredenzialiException("Richiesta autenticazione basic del gestore delle credenziali, ma password non definito");
  183.             }
  184.             if(credenzialiTrasporto.getUsername()==null || credenzialiTrasporto.getPassword()==null){
  185.                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_CREDENTIALS_NOT_FOUND,
  186.                         buildWWWProxyAuthBasic(authType, realm, true),
  187.                         getPrefixMessaggioAutenticazioneFallita(autenticazioneGateway.getValore())+"nessun tipo di credenziali basic riscontrata nel trasporto");
  188.             }
  189.             if( ! ( usernameGateway.equals(credenzialiTrasporto.getUsername()) && passwordGateway.equals(credenzialiTrasporto.getPassword()) ) ){
  190.                 String credenzialiPresenti = credenzialiTrasporto.toString();
  191.                 if(credenzialiPresenti==null || credenzialiPresenti.equals("")){
  192.                     throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_INVALID_CREDENTIALS,
  193.                             buildWWWProxyAuthBasic(authType, realm, false),
  194.                             getPrefixMessaggioAutenticazioneFallita(autenticazioneGateway.getValore())+NESSUN_TIPO_CREDENZIALI_TRASPORTO);
  195.                 }else{
  196.                     throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_INVALID_CREDENTIALS,
  197.                             buildWWWProxyAuthBasic(authType, realm, false),
  198.                             getPrefixMessaggioAutenticazioneFallita(autenticazioneGateway.getValore())+CREDENZIALI_PRESENTI_TRASPORTO+credenzialiPresenti);
  199.                 }
  200.             }
  201.         }
  202.         else if(TipoAutenticazioneGestoreCredenziali.SSL.equals(autenticazioneGateway)){
  203.             String subjectGateway = configurazione.getAutenticazioneCanaleSslSubject();
  204.             if(subjectGateway == null){
  205.                 throw new GestoreCredenzialiException("Richiesta autenticazione ssl del gestore delle credenziali, ma subject non definito");
  206.             }
  207.             try{
  208.                 org.openspcoop2.utils.certificate.CertificateUtils.validaPrincipal(subjectGateway, PrincipalType.SUBJECT);
  209.             }catch(Exception e){
  210.                 throw new GestoreCredenzialiException("Richiesta autenticazione ssl del gestore delle credenziali, ma subject fornito ["+subjectGateway+"] non valido: "+e.getMessage());
  211.             }
  212.             if(credenzialiTrasporto.getSubject()==null){
  213.                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_CREDENTIALS_NOT_FOUND,
  214.                         buildWWWProxyAuthSSL(authType, realm, true),
  215.                         getPrefixMessaggioAutenticazioneFallita(autenticazioneGateway.getValore())+"nessun tipo di credenziali ssl riscontrata nel trasporto");
  216.             }
  217.             try{
  218.                 if( ! org.openspcoop2.utils.certificate.CertificateUtils.sslVerify(subjectGateway, credenzialiTrasporto.getSubject(), PrincipalType.SUBJECT, OpenSPCoop2Logger.getLoggerOpenSPCoopCore()) ){
  219.                     String credenzialiPresenti = credenzialiTrasporto.toString();
  220.                     if(credenzialiPresenti==null || credenzialiPresenti.equals("")){
  221.                         throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_INVALID_CREDENTIALS,
  222.                                 buildWWWProxyAuthSSL(authType, realm, false),
  223.                                 getPrefixMessaggioAutenticazioneFallita(autenticazioneGateway.getValore())+NESSUN_TIPO_CREDENZIALI_TRASPORTO);
  224.                     }else{
  225.                         throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_INVALID_CREDENTIALS,
  226.                                 buildWWWProxyAuthSSL(authType, realm, false),
  227.                                 getPrefixMessaggioAutenticazioneFallita(autenticazioneGateway.getValore())+CREDENZIALI_PRESENTI_TRASPORTO+credenzialiPresenti);
  228.                     }
  229.                 }
  230.             }
  231.             catch(GestoreCredenzialiConfigurationException ge) {
  232.                 throw ge;
  233.             }
  234.             catch(Exception e){
  235.                 throw new GestoreCredenzialiException("Richiesta autenticazione ssl del gateway gestore delle credenziali; errore durante la verifica: "+e.getMessage());
  236.             }
  237.         }
  238.         else if(TipoAutenticazioneGestoreCredenziali.PRINCIPAL.equals(autenticazioneGateway)){
  239.             String principalGateway = configurazione.getAutenticazioneCanalePrincipal();
  240.             if(principalGateway == null){
  241.                 throw new GestoreCredenzialiException("Richiesta autenticazione principal del gestore delle credenziali, ma principal non definito");
  242.             }
  243.             if(credenzialiTrasporto.getPrincipal()==null){
  244.                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_CREDENTIALS_NOT_FOUND,
  245.                         buildWWWProxyAuthPrincipal(authType, realm, true),
  246.                         getPrefixMessaggioAutenticazioneFallita(autenticazioneGateway.getValore())+"nessun tipo di credenziale principal riscontrata nel trasporto");
  247.             }
  248.             if( ! ( principalGateway.equals(credenzialiTrasporto.getPrincipal()) ) ){
  249.                 String credenzialiPresenti = credenzialiTrasporto.toString();
  250.                 if(credenzialiPresenti==null || credenzialiPresenti.equals("")){
  251.                     throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_INVALID_CREDENTIALS,
  252.                             buildWWWProxyAuthPrincipal(authType, realm, false),
  253.                             getPrefixMessaggioAutenticazioneFallita(autenticazioneGateway.getValore())+NESSUN_TIPO_CREDENZIALI_TRASPORTO);
  254.                 }else{
  255.                     throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_INVALID_CREDENTIALS,
  256.                             buildWWWProxyAuthPrincipal(authType, realm, false),
  257.                             getPrefixMessaggioAutenticazioneFallita(autenticazioneGateway.getValore())+CREDENZIALI_PRESENTI_TRASPORTO+credenzialiPresenti);
  258.                 }
  259.             }
  260.         }
  261.        
  262.        
  263.         // Modalità di gestione
  264.        
  265.         ModalitaAutenticazioneGestoreCredenziali modalita = configurazione.getModalitaAutenticazioneCanale();
  266.         String modalitaAtLeastOneErrorDescription = null;
  267.         if(ModalitaAutenticazioneGestoreCredenziali.AT_LEAST_ONE.equals(modalita)) {
  268.             modalitaAtLeastOneErrorDescription = configurazione.getModalitaAutenticazioneCanaleAtLeastOneErrorDescription();
  269.         }
  270.        
  271.        
  272.         // Avvio processo di lettura credenziali portate nell'header HTTP e generate in seguito all'autenticazione effettuata dal componente Gateway
  273.        
  274.         Credenziali c = new Credenziali();  
  275.        
  276.         String headerNameBasicUsername = configurazione.getHeaderBasicUsername();
  277.         String headerNameBasicPassword = configurazione.getHeaderBasicPassword();
  278.         boolean verificaIdentitaBasic = headerNameBasicUsername!=null && headerNameBasicPassword!=null;
  279.        
  280.         String headerNameSSLSubject = configurazione.getHeaderSslSubject();
  281.         String headerNameSSLIssuer = configurazione.getHeaderSslIssuer();
  282.         String headerNameSSLCertificate = configurazione.getHeaderSslCertificate();
  283.         KeyStore trustStoreCertificatiX509 = null;
  284.         if(configurazione.getHeaderSslCertificateTrustStorePath()!=null) {
  285.             try {
  286.                 trustStoreCertificatiX509 = GestoreKeystoreCaching.getMerlinTruststore(this.requestInfo, configurazione.getHeaderSslCertificateTrustStorePath(),
  287.                         configurazione.getHeaderSslCertificateTrustStoreType(),
  288.                         configurazione.getHeaderSslCertificateTrustStorePassword()).getTrustStore();
  289.             }catch(Exception e){
  290.                 throw new GestoreCredenzialiException("Richiesta autenticazione ssl del gateway gestore delle credenziali; errore durante la lettura del truststore indicato ("+configurazione.getHeaderSslCertificateTrustStorePath()+"): "+e.getMessage());
  291.             }
  292.         }
  293.         boolean trustStoreCertificatiX509CheckValid = configurazione.isHeaderSslCertificateTrustStoreCheckValid();
  294.         CertStore trustStoreCertificatiX509Crls = null;
  295.        
  296.         IOCSPValidator ocspValidator = null;
  297.         if(trustStoreCertificatiX509!=null) {
  298.             boolean crlByOcsp = false;
  299.             if(configurazione.getHeaderSslCertificateOcspPolicy()!=null) {
  300.                 LoggerBuffer lb = new LoggerBuffer();
  301.                 lb.setLogDebug(OpenSPCoop2Logger.getLoggerOpenSPCoopCore());
  302.                 lb.setLogError(OpenSPCoop2Logger.getLoggerOpenSPCoopCore());
  303.                 GestoreOCSPResource ocspResourceReader = new GestoreOCSPResource(this.requestInfo);
  304.                 try {
  305.                     ocspValidator = new GestoreOCSPValidator(this.requestInfo, lb,
  306.                             trustStoreCertificatiX509,
  307.                             configurazione.getHeaderSslCertificateCrlX509(),
  308.                             configurazione.getHeaderSslCertificateOcspPolicy(),
  309.                             ocspResourceReader);
  310.                 }catch(Exception e){
  311.                     throw new GestoreCredenzialiException("Richiesta autenticazione ssl del gateway gestore delle credenziali; errore durante l'inizializzazione del gestore della policy OCSP ("+configurazione.getHeaderSslCertificateOcspPolicy()+"): "+e.getMessage());
  312.                 }
  313.                 if(ocspValidator!=null) {
  314.                     GestoreOCSPValidator gOcspValidator = (GestoreOCSPValidator) ocspValidator;
  315.                     if(gOcspValidator.getOcspConfig()!=null) {
  316.                         crlByOcsp = gOcspValidator.getOcspConfig().isCrl();
  317.                     }
  318.                 }
  319.             }
  320.             if(configurazione.getHeaderSslCertificateCrlX509()!=null && !crlByOcsp) {
  321.                 try {
  322.                     trustStoreCertificatiX509Crls = GestoreKeystoreCaching.getCRLCertstore(this.requestInfo, configurazione.getHeaderSslCertificateCrlX509()).getCertStore();
  323.                 }catch(Exception e){
  324.                     throw new GestoreCredenzialiException("Richiesta autenticazione ssl del gateway gestore delle credenziali; errore durante la lettura delle CRLs ("+configurazione.getHeaderSslCertificateCrlX509()+"): "+e.getMessage());
  325.                 }
  326.             }
  327.         }
  328.         boolean sslCertificateUrlDecode = false;
  329.         boolean sslCertificateBase64Decode = false;
  330.         boolean sslCertificateHexDecode = false;
  331.         boolean sslCertificateUrlDecodeOrBase64Decode = false;
  332.         boolean sslCertificateUrlDecodeOrBase64DecodeOrHexDecode = false;
  333.         boolean sslCertificateEnrichBeginEnd = false;
  334.         boolean sslCertificateReplace = false;
  335.         String sslCertificateReplaceSource = null;
  336.         String sslCertificateReplaceDest = null;
  337.         String sslCertificateNoneOption = null;
  338.         boolean sslCertificateIgnoreEmpty = false;
  339.         if(headerNameSSLCertificate!=null) {
  340.             sslCertificateUrlDecode = configurazione.isHeaderSslCertificateUrlDecode();
  341.             sslCertificateBase64Decode = configurazione.isHeaderSslCertificateBase64Decode();
  342.             sslCertificateHexDecode = configurazione.isHeaderSslCertificateHexDecode();
  343.             sslCertificateUrlDecodeOrBase64Decode = configurazione.isHeaderSslCertificateUrlDecodeOrBase64Decode();
  344.             sslCertificateUrlDecodeOrBase64DecodeOrHexDecode = configurazione.isHeaderSslCertificateUrlDecodeOrBase64DecodeOrHexDecode();
  345.             sslCertificateEnrichBeginEnd = configurazione.isHeaderSslCertificateEnrichBeginEnd();
  346.             sslCertificateReplace = configurazione.isHeaderSslCertificateReplaceCharacters();
  347.             if(sslCertificateReplace) {
  348.                 sslCertificateReplaceSource = configurazione.getHeaderSslCertificateReplaceCharactersSource();
  349.                 sslCertificateReplaceDest = configurazione.getHeaderSslCertificateReplaceCharactersDest();
  350.             }
  351.             sslCertificateNoneOption = configurazione.getHeaderSslCertificateNoneOption();
  352.             sslCertificateIgnoreEmpty = configurazione.isHeaderSslCertificateIgnoreEmpty();
  353.         }
  354.         boolean verificaIdentitaSSL = headerNameSSLSubject!=null || headerNameSSLCertificate!=null;
  355.        
  356.         String headerNamePrincipal = configurazione.getHeaderPrincipal();
  357.         boolean verificaIdentitaPrincipal = headerNamePrincipal!=null;
  358.        
  359.         if(!verificaIdentitaBasic && !verificaIdentitaSSL && !verificaIdentitaPrincipal){
  360.             return credenzialiTrasporto; // credenziali originali
  361.         }
  362.        
  363.         boolean existsHeaderBasicUsername = false;
  364.         boolean existsHeaderBasicPassword = false;
  365.         if(verificaIdentitaBasic){
  366.             existsHeaderBasicUsername = existsHeader(headerTrasporto, headerNameBasicUsername);
  367.             existsHeaderBasicPassword = existsHeader(headerTrasporto, headerNameBasicPassword);
  368.         }
  369.         boolean existsHeaderSslSubject = false;
  370.         boolean existsHeaderSslIssuer = false;
  371.         boolean existsHeaderSslCertificate = false;
  372.         if(verificaIdentitaSSL){
  373.             existsHeaderSslSubject = existsHeader(headerTrasporto, headerNameSSLSubject);
  374.             existsHeaderSslIssuer = existsHeader(headerTrasporto, headerNameSSLIssuer);
  375.             existsHeaderSslCertificate = existsHeader(headerTrasporto, headerNameSSLCertificate);
  376.         }
  377.         boolean existsHeaderPrincipal = false;
  378.         if(verificaIdentitaPrincipal){
  379.             existsHeaderPrincipal = existsHeader(headerTrasporto, headerNamePrincipal);
  380.         }
  381.        
  382.        
  383.         // Interpretazione della modalità richiesta di gestione
  384.         // Il Gestore può funzionare in modalità 'none' e quindi le richieste in arrivo possono anche non presentare alcun header che veicola le credenziali.
  385.         // L'unico vincolo è che se vi sono delle credenziali devono essere valide (non vuote e corrette per ssl).
  386.         // Il Gestore può inoltre essere configurato per richiedere almeno una credenziale o esattamente una credenziale di un certo tipo.
  387.         // Con la modalità 'none' o 'atLeastOne' è possibile usare il gestore davanti a erogazioni/fruizioni con tipi di autenticazione differenti,
  388.         // delegando poi alla singola erogazione o fruizione il controllo che le credenziali siano effetivamente presenti
  389.         switch (modalita) {
  390.         case NONE:
  391.             if( (!existsHeaderBasicUsername || !existsHeaderBasicPassword) && !existsHeaderSslSubject && !existsHeaderSslCertificate && !existsHeaderPrincipal ){
  392.                 return credenzialiTrasporto; // credenziali originali poiche' non sono presenti header che indicano nuove credenziali.  
  393.             }
  394.             break;
  395.         case AT_LEAST_ONE:
  396.             if( (!existsHeaderBasicUsername || !existsHeaderBasicPassword) && !existsHeaderSslSubject && !existsHeaderSslCertificate && !existsHeaderPrincipal ){
  397.                 StringBuilder sb = new StringBuilder();
  398.                 if(headerNameBasicUsername!=null) {
  399.                     sb.append(headerNameBasicUsername);
  400.                 }
  401.                 if(headerNameSSLSubject!=null) {
  402.                     if(sb.length()>0) {
  403.                         sb.append(",");
  404.                     }
  405.                     sb.append(headerNameSSLSubject);
  406.                 }
  407.                 if(headerNameSSLCertificate!=null) {
  408.                     if(sb.length()>0) {
  409.                         sb.append(",");
  410.                     }
  411.                     sb.append(headerNameSSLCertificate);
  412.                 }
  413.                 if(headerNamePrincipal!=null) {
  414.                     if(sb.length()>0) {
  415.                         sb.append(",");
  416.                     }
  417.                     sb.append(headerNamePrincipal);
  418.                 }
  419.                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  420.                         buildWWWProxyAuthAtleastOne(authType, realm,
  421.                                 modalitaAtLeastOneErrorDescription),
  422.                         "Non sono presenti Header HTTP che veicolano credenziali (header non rilevati: "+sb.toString()+")");
  423.             }
  424.             break;
  425.         case BASIC:
  426.             if(!verificaIdentitaBasic){
  427.                 throw new GestoreCredenzialiException(getConfigurazioneNonValidaHeaderNonDefiniti(modalita, modalita.getValore()));
  428.             }
  429.             if( !existsHeaderBasicUsername ) {
  430.                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  431.                         buildWWWAuthBasic(),
  432.                         getMessaggioHeaderHttpNonPresente(headerNameBasicUsername));
  433.             }
  434.             if( !existsHeaderBasicPassword ) {
  435.                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  436.                         buildWWWAuthBasic(),
  437.                         getMessaggioHeaderHttpNonPresente(headerNameBasicPassword));
  438.             }
  439.             // il controllo che il valore presente negli header non sia vuoto viene fatto dopo.
  440.             break;
  441.         case SSL:
  442.             if(!verificaIdentitaSSL){
  443.                 throw new GestoreCredenzialiException(getConfigurazioneNonValidaAlmenoHeaderDefinito(modalita, modalita.getValore()));
  444.             }
  445.             if(headerNameSSLSubject!=null && headerNameSSLCertificate!=null) {
  446.                 if(!existsHeaderSslSubject && !existsHeaderSslCertificate) {
  447.                     throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  448.                             buildWWWAuthSSL(),
  449.                             "Header HTTP '"+headerNameSSLSubject+"' o '"+headerNameSSLCertificate+"' non presente");
  450.                 }
  451.             }
  452.             else if( headerNameSSLSubject!=null) {
  453.                 if(!existsHeaderSslSubject) {
  454.                     throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  455.                             buildWWWAuthSSL(),
  456.                             getMessaggioHeaderHttpNonPresente(headerNameSSLSubject));
  457.                 }
  458.             }
  459.             else { /** per forza questo caso if( headerNameSSLCertificate!=null */
  460.                 if( !existsHeaderSslCertificate) {
  461.                     throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  462.                             buildWWWAuthSSL(),
  463.                             getMessaggioHeaderHttpNonPresente(headerNameSSLCertificate));
  464.                 }
  465.             }
  466.             // il controllo che il valore presente negli header non sia vuoto e/o corretto viene fatto dopo.
  467.             break;
  468.         case PRINCIPAL:
  469.             if(!verificaIdentitaPrincipal){
  470.                 throw new GestoreCredenzialiException(getConfigurazioneNonValidaHeaderNonDefinito(modalita, modalita.getValore()));
  471.             }
  472.             if( !existsHeaderPrincipal) {
  473.                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  474.                         buildWWWAuthPrincipal(),
  475.                         getMessaggioHeaderHttpNonPresente(headerNamePrincipal));
  476.             }
  477.             // il controllo che il valore presente negli header non sia vuoto viene fatto dopo.
  478.             break;
  479.         default:
  480.             break;
  481.         }
  482.        

  483.                
  484.         // Lettura credenziali Basic
  485.         if(verificaIdentitaBasic &&
  486.                 existsHeaderBasicUsername &&
  487.                 existsHeaderBasicPassword ){
  488.            
  489.             String username = getProperty(headerTrasporto,  headerNameBasicUsername );
  490.             String password = getProperty(headerTrasporto,  headerNameBasicPassword );
  491.             if(username==null || "".equals(username)){
  492.                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  493.                         buildWWWAuthBasic(),
  494.                         "Username value non fornito nell'header del trasporto "+headerNameBasicUsername);
  495.             }
  496.             if(password==null || "".equals(password)){
  497.                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  498.                         buildWWWAuthBasic(),
  499.                         "Password value non fornito nell'header del trasporto "+headerNameBasicPassword);
  500.             }
  501.             c.setUsername(username);
  502.             c.setPassword(password);
  503.         }
  504.        
  505.         // Lettura credenziali ssl
  506.         if(verificaIdentitaSSL) {
  507.             if(existsHeaderSslSubject ){
  508.                
  509.                 String subject = getProperty(headerTrasporto,   headerNameSSLSubject );
  510.                 if(subject==null || "".equals(subject)){
  511.                     throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  512.                             buildWWWAuthSSL(),
  513.                             "Subject value non fornito nell'header del trasporto "+headerNameSSLSubject);
  514.                 }
  515.                 try{
  516.                     org.openspcoop2.utils.certificate.CertificateUtils.formatPrincipal(subject, PrincipalType.SUBJECT);
  517.                     /** Non posso validare, verra' fornito un certificato nel formato RFC 2253 o RFC 1779
  518.                     Sicuramente puo' contenere sia il carattere '/' che ',' ma uno dei due sara' escaped tramite il formato richiesto.
  519.                     org.openspcoop.utils.Utilities.validaSubject(subject);*/
  520.                 }catch(Exception e){
  521.                     throw new GestoreCredenzialiException("Subject value fornito nell'header del trasporto "+headerNameSSLSubject+getSuffixNonValido(e),e);
  522.                 }
  523.                 c.setSubject(subject);
  524.             }
  525.             if(existsHeaderSslIssuer ){
  526.                
  527.                 String issuer = getProperty(headerTrasporto,    headerNameSSLIssuer );
  528.                 if(issuer==null || "".equals(issuer)){
  529.                     throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  530.                             buildWWWAuthSSL(),
  531.                             "Issuer value non fornito nell'header del trasporto "+headerNameSSLIssuer);
  532.                 }
  533.                 try{
  534.                     org.openspcoop2.utils.certificate.CertificateUtils.formatPrincipal(issuer, PrincipalType.ISSUER);
  535.                     /**Non posso validare, verra' fornito un certificato nel formato RFC 2253 o RFC 1779
  536.                     Sicuramente puo' contenere sia il carattere '/' che ',' ma uno dei due sara' escaped tramite il formato richiesto.
  537.                     org.openspcoop.utils.Utilities.validaSubject(subject);*/
  538.                 }catch(Exception e){
  539.                     throw new GestoreCredenzialiException("Issuer value fornito nell'header del trasporto "+headerNameSSLIssuer+getSuffixNonValido(e),e);
  540.                 }
  541.                 c.setIssuer(issuer);
  542.             }
  543.             if(existsHeaderSslCertificate ){
  544.                
  545.                 String certificate = getProperty(headerTrasporto,   headerNameSSLCertificate );
  546.                
  547.                 if(certificate!=null &&
  548.                         (
  549.                                 (sslCertificateNoneOption!=null && sslCertificateNoneOption.equals(certificate))
  550.                                 ||
  551.                                 (StringUtils.isEmpty(certificate) && sslCertificateIgnoreEmpty)
  552.                         )
  553.                     ){
  554.                     c.setCertificate(null);
  555.                     c.setSubject(null);
  556.                     c.setIssuer(null);
  557.                     SecurityToken securityToken = SecurityTokenUtilities.readSecurityToken(this.context);
  558.                     if(securityToken!=null) {
  559.                         securityToken.setChannel(null); // sovrascrivo eventuali esistente
  560.                     }
  561.                 }
  562.                 else {
  563.                
  564.                     if(certificate==null || "".equals(certificate)){
  565.                         throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  566.                                 buildWWWAuthSSL(),
  567.                                 "Certificate non fornito nell'header del trasporto "+headerNameSSLCertificate);
  568.                     }
  569.                    
  570.                                    
  571.                     CertificateDecodeConfig config = new CertificateDecodeConfig();
  572.                     config.setUrlDecode(sslCertificateUrlDecode);
  573.                     config.setBase64Decode(sslCertificateBase64Decode);
  574.                     config.setHexDecode(sslCertificateHexDecode);
  575.                     config.setUrlDecodeOrBase64Decode(sslCertificateUrlDecodeOrBase64Decode);
  576.                     config.setUrlDecodeOrBase64DecodeOrHexDecode(sslCertificateUrlDecodeOrBase64DecodeOrHexDecode);
  577.                     config.setEnrichPEMBeginEnd(sslCertificateEnrichBeginEnd);
  578.                     config.setReplace(sslCertificateReplace);
  579.                     if(sslCertificateReplace) {
  580.                         if(sslCertificateReplaceSource!=null && !StringUtils.isEmpty(sslCertificateReplaceSource)) {
  581.                             config.setReplaceSource(sslCertificateReplaceSource);
  582.                         }
  583.                         if(sslCertificateReplaceDest!=null && !StringUtils.isEmpty(sslCertificateReplaceDest)) {
  584.                             config.setReplaceDest(sslCertificateReplaceDest);
  585.                         }
  586.                     }
  587.    
  588.                     Certificate cer = null;
  589.                     try{
  590.                         cer = CertificateUtils.readCertificate(config, certificate);                    
  591.                         c.setCertificate(cer);
  592.                        
  593.                         String subject = c.getCertificate().getCertificate().getSubject().toString();
  594.                         String issuer = c.getCertificate().getCertificate().getIssuer().toString();
  595.                         c.setSubject(subject);
  596.                         c.setIssuer(issuer);
  597.                        
  598.                     }catch(Exception e){
  599.                         throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  600.                                 buildWWWAuthSSL(),
  601.                                 "Certificate fornito nell'header del trasporto "+headerNameSSLCertificate+getSuffixNonValido(e), e);
  602.                     }
  603.                    
  604.                     if(cer!=null && trustStoreCertificatiX509!=null) {
  605.                         if(!cer.getCertificate().isVerified(trustStoreCertificatiX509, true)) {
  606.                             throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  607.                                     buildWWWAuthSSL(),
  608.                                     "Certificato presente nell'header '"+headerNameSSLCertificate+"' non è verificabile rispetto alle CA conosciute");
  609.                         }
  610.                         if(trustStoreCertificatiX509Crls!=null) {
  611.                             try {
  612.                                 cer.getCertificate().checkValid(trustStoreCertificatiX509Crls, trustStoreCertificatiX509);
  613.                             }catch(Exception t) {
  614.                                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  615.                                         buildWWWAuthSSL(),
  616.                                         getMessaggioCertificatoPresenteHeaderNonValido(headerNameSSLCertificate,t));
  617.                             }
  618.                         }
  619.                         else if(trustStoreCertificatiX509CheckValid){
  620.                             try {
  621.                                 cer.getCertificate().checkValid();
  622.                             }catch(Exception t) {
  623.                                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  624.                                         buildWWWAuthSSL(),
  625.                                         getMessaggioCertificatoPresenteHeaderNonValido(headerNameSSLCertificate,t));
  626.                             }
  627.                         }
  628.                         if(ocspValidator!=null) {
  629.                             try {
  630.                                 ocspValidator.valid(cer.getCertificate().getCertificate());
  631.                             }catch(Exception t) {
  632.                                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  633.                                         buildWWWAuthSSL(),
  634.                                         getMessaggioCertificatoPresenteHeaderNonValido(headerNameSSLCertificate,t));
  635.                             }
  636.                         }
  637.                     }
  638.                    
  639.                     /* --------------- SecurityToken --------------- */
  640.                     try {
  641.                         if(cer!=null && this.context!=null) {
  642.                             SecurityToken securityToken = SecurityTokenUtilities.newSecurityToken(this.context);
  643.                             ChannelSecurityToken channelSecurityToken = new ChannelSecurityToken();
  644.                             channelSecurityToken.setCertificate(cer.getCertificate());
  645.                             securityToken.setChannel(channelSecurityToken); // sovrascrivo eventuali esistente
  646.                         }
  647.                     }catch(Exception e){
  648.                         throw new GestoreCredenzialiException("Costruzione SecurityToken non riuscita: "+e.getMessage(),e);
  649.                     }
  650.                 }
  651.             }
  652.         }
  653.        
  654.         // Lettura credenziali principal
  655.         if(verificaIdentitaPrincipal &&
  656.                 existsHeaderPrincipal ){
  657.            
  658.             String principal = getProperty(headerTrasporto,     headerNamePrincipal );
  659.             if(principal==null || "".equals(principal)){
  660.                 throw new GestoreCredenzialiConfigurationException(IntegrationFunctionError.PROXY_AUTHENTICATION_FORWARDED_CREDENTIALS_NOT_FOUND,
  661.                         buildWWWAuthPrincipal(),
  662.                         "Principal value non fornito nell'header del trasporto "+headerNamePrincipal);
  663.             }
  664.             c.setPrincipal(principal);
  665.         }
  666.        
  667.         return c;
  668.        
  669.     }
  670.    
  671.     public String getIdentitaGestoreCredenziali(){
  672.         return this.identita;
  673.     }
  674.    
  675.     private boolean existsHeader(Map<String, List<String>> properties, String name){
  676.         if(properties!=null){
  677.             return TransportUtils.containsKey(properties, name);
  678.         }else{
  679.             return false;
  680.         }
  681.     }
  682.    
  683.     private String getProperty(Map<String, List<String>> properties, String name){
  684.         if(properties!=null){
  685.             return TransportUtils.getFirstValue(properties, name);
  686.         }else{
  687.             return null;
  688.         }
  689.        
  690.     }
  691.    
  692.     public static String buildWWWProxyAuthBasic(String authType, String realm, boolean missing) {
  693.         if(realm==null || "".equals(realm) || authType==null || "".equals(authType)) {
  694.             return null;
  695.         }
  696.         WWWAuthenticateConfig configGW = OpenSPCoop2Properties.getInstance().getRealmAutenticazioneBasicWWWAuthenticateConfig();
  697.         WWWAuthenticateConfig proxy = configGW!=null ? (WWWAuthenticateConfig) configGW.clone() : new WWWAuthenticateConfig();
  698.         proxy.setRealm(realm);
  699.         proxy.setAuthType(authType);
  700.         return missing ? proxy.buildWWWAuthenticateHeaderValue_notFound() : proxy.buildWWWAuthenticateHeaderValue_invalid();
  701.     }
  702.     public static String buildWWWProxyAuthSSL(String authType, String realm, boolean missing) {
  703.         if(realm==null || "".equals(realm) || authType==null || "".equals(authType)) {
  704.             return null;
  705.         }
  706.         WWWAuthenticateConfig configGW = OpenSPCoop2Properties.getInstance().getRealmAutenticazioneHttpsWWWAuthenticateConfig();
  707.         WWWAuthenticateConfig proxy = configGW!=null ? (WWWAuthenticateConfig) configGW.clone() : new WWWAuthenticateConfig();
  708.         proxy.setRealm(realm);
  709.         proxy.setAuthType(authType);
  710.         return missing ? proxy.buildWWWAuthenticateHeaderValue_notFound() : proxy.buildWWWAuthenticateHeaderValue_invalid();
  711.     }
  712.     public static String buildWWWProxyAuthPrincipal(String authType, String realm, boolean missing) {
  713.         if(realm==null || "".equals(realm) || authType==null || "".equals(authType)) {
  714.             return null;
  715.         }
  716.         WWWAuthenticateConfig configGW = OpenSPCoop2Properties.getInstance().getRealmAutenticazionePrincipalWWWAuthenticateConfig(TipoAutenticazionePrincipal.CONTAINER);
  717.         WWWAuthenticateConfig proxy = configGW!=null ? (WWWAuthenticateConfig) configGW.clone() : new WWWAuthenticateConfig();
  718.         proxy.setRealm(realm);
  719.         proxy.setAuthType(authType);
  720.         return missing ? proxy.buildWWWAuthenticateHeaderValue_notFound() : proxy.buildWWWAuthenticateHeaderValue_invalid();
  721.     }
  722.     public static String buildWWWProxyAuthAtleastOne(String authType, String realm, String errorDescription) {
  723.         if(realm==null || "".equals(realm) || authType==null || "".equals(authType)) {
  724.             return null;
  725.         }
  726.         if(errorDescription!=null && !"".equals(errorDescription)) {
  727.             return WWWAuthenticateGenerator.buildCustomHeaderValue(authType, realm, WWWAuthenticateErrorCode.invalid_request,
  728.                     errorDescription);
  729.         }
  730.         else {
  731.             WWWAuthenticateErrorCode errorCode = null;
  732.             return WWWAuthenticateGenerator.buildCustomHeaderValue(authType, realm, errorCode, null);
  733.         }
  734.     }

  735.    
  736.     public static String buildWWWAuthBasic() {
  737.         WWWAuthenticateConfig config = OpenSPCoop2Properties.getInstance().getRealmAutenticazioneBasicWWWAuthenticateConfig();
  738.         if(config!=null) {
  739.             return config.buildWWWAuthenticateHeaderValue_notFound();
  740.         }
  741.         return null;
  742.     }
  743.     public static String buildWWWAuthSSL() {
  744.         WWWAuthenticateConfig config = OpenSPCoop2Properties.getInstance().getRealmAutenticazioneHttpsWWWAuthenticateConfig();
  745.         if(config!=null) {
  746.             return config.buildWWWAuthenticateHeaderValue_notFound();
  747.         }
  748.         return null;
  749.     }
  750.     public static String buildWWWAuthPrincipal() {
  751.         WWWAuthenticateConfig config = OpenSPCoop2Properties.getInstance().getRealmAutenticazionePrincipalWWWAuthenticateConfig(TipoAutenticazionePrincipal.CONTAINER);
  752.         if(config!=null) {
  753.             return config.buildWWWAuthenticateHeaderValue_notFound();
  754.         }
  755.         return null;
  756.     }
  757. }