ModIValidazioneSintatticaSoap.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.modipa.validator;

  21. import java.security.cert.X509Certificate;
  22. import java.util.ArrayList;
  23. import java.util.Date;
  24. import java.util.HashMap;
  25. import java.util.Iterator;
  26. import java.util.List;
  27. import java.util.Map;
  28. import java.util.Properties;

  29. import javax.xml.soap.AttachmentPart;
  30. import javax.xml.soap.SOAPEnvelope;
  31. import javax.xml.soap.SOAPHeaderElement;

  32. import org.apache.commons.lang.StringUtils;
  33. import org.apache.wss4j.dom.WSDataRef;
  34. import org.apache.wss4j.dom.message.token.Timestamp;
  35. import org.openspcoop2.core.config.PortaApplicativa;
  36. import org.openspcoop2.core.constants.CostantiLabel;
  37. import org.openspcoop2.core.id.IDPortaApplicativa;
  38. import org.openspcoop2.message.OpenSPCoop2Message;
  39. import org.openspcoop2.message.OpenSPCoop2MessageFactory;
  40. import org.openspcoop2.message.OpenSPCoop2SoapMessage;
  41. import org.openspcoop2.message.soap.reference.Reference;
  42. import org.openspcoop2.message.soap.wsaddressing.Costanti;
  43. import org.openspcoop2.message.soap.wsaddressing.WSAddressingHeader;
  44. import org.openspcoop2.message.soap.wsaddressing.WSAddressingUtilities;
  45. import org.openspcoop2.message.xml.MessageDynamicNamespaceContextFactory;
  46. import org.openspcoop2.message.xml.XPathExpressionEngine;
  47. import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
  48. import org.openspcoop2.pdd.core.dynamic.DynamicUtils;
  49. import org.openspcoop2.pdd.logger.MsgDiagnostico;
  50. import org.openspcoop2.protocol.modipa.builder.ModIImbustamentoSoap;
  51. import org.openspcoop2.protocol.modipa.config.ModIProperties;
  52. import org.openspcoop2.protocol.modipa.constants.ModICostanti;
  53. import org.openspcoop2.protocol.modipa.utils.ModISecurityConfig;
  54. import org.openspcoop2.protocol.modipa.utils.ModITruststoreConfig;
  55. import org.openspcoop2.protocol.modipa.utils.ModIUtilities;
  56. import org.openspcoop2.protocol.modipa.utils.SOAPInfo;
  57. import org.openspcoop2.protocol.sdk.Busta;
  58. import org.openspcoop2.protocol.sdk.Context;
  59. import org.openspcoop2.protocol.sdk.Eccezione;
  60. import org.openspcoop2.protocol.sdk.IProtocolFactory;
  61. import org.openspcoop2.protocol.sdk.ProtocolException;
  62. import org.openspcoop2.protocol.sdk.SecurityToken;
  63. import org.openspcoop2.protocol.sdk.SoapMessageSecurityToken;
  64. import org.openspcoop2.protocol.sdk.constants.CodiceErroreCooperazione;
  65. import org.openspcoop2.protocol.sdk.state.IState;
  66. import org.openspcoop2.protocol.sdk.state.RequestInfo;
  67. import org.openspcoop2.protocol.sdk.validator.ValidazioneUtils;
  68. import org.openspcoop2.security.keystore.KeystoreConstants;
  69. import org.openspcoop2.security.message.MessageSecurityContext;
  70. import org.openspcoop2.security.message.MessageSecurityContextParameters;
  71. import org.openspcoop2.security.message.SubErrorCodeSecurity;
  72. import org.openspcoop2.security.message.constants.SecurityConstants;
  73. import org.openspcoop2.security.message.constants.SignatureDigestAlgorithm;
  74. import org.openspcoop2.security.message.constants.WSSAttachmentsConstants;
  75. import org.openspcoop2.security.message.engine.MessageSecurityContext_impl;
  76. import org.openspcoop2.security.message.saml.SAMLBuilderConfigConstants;
  77. import org.openspcoop2.security.message.wss4j.MessageSecurityReceiver_wss4j;
  78. import org.openspcoop2.utils.certificate.CertificateInfo;
  79. import org.openspcoop2.utils.date.DateUtils;
  80. import org.openspcoop2.utils.io.Base64Utilities;
  81. import org.openspcoop2.utils.xml.DynamicNamespaceContext;
  82. import org.openspcoop2.utils.xml.XPathNotFoundException;
  83. import org.openspcoop2.utils.xml.XPathReturnType;
  84. import org.slf4j.Logger;
  85. import org.w3c.dom.NodeList;

  86. /**
  87.  * ModIValidazioneSintatticaSoap
  88.  *
  89.  * @author Poli Andrea (apoli@link.it)
  90.  * @author $Author$
  91.  * @version $Rev$, $Date$
  92.  */
  93. public class ModIValidazioneSintatticaSoap extends AbstractModIValidazioneSintatticaCommons{

  94.     public ModIValidazioneSintatticaSoap(Logger log, IState state, Context context, IProtocolFactory<?> factory, RequestInfo requestInfo,
  95.             ModIProperties modiProperties, ValidazioneUtils validazioneUtils) {
  96.         super(log, state, context, factory, requestInfo, modiProperties, validazioneUtils);
  97.     }
  98.    
  99.     private void logError(String msg) {
  100.         this.log.error(msg);
  101.     }
  102.     private void logError(String msg, Exception e) {
  103.         this.log.error(msg,e);
  104.     }
  105.    
  106.     private String getErrorHeaderSoapNonPresente(String hdr) {
  107.         return "Header SOAP '"+hdr+"' non presente";
  108.     }
  109.    
  110.     public void validateAsyncInteractionProfile(OpenSPCoop2Message msg, boolean request, String asyncInteractionType, String asyncInteractionRole,
  111.             Busta busta, List<Eccezione> erroriValidazione,
  112.             String replyTo) throws ProtocolException {
  113.        
  114.         boolean bufferMessageReadOnly = this.modiProperties.isValidazioneBufferEnabled();
  115.         String idTransazione = null;
  116.         if(this.context!=null) {
  117.             idTransazione = (String)this.context.getObject(org.openspcoop2.core.constants.Costanti.ID_TRANSAZIONE);
  118.         }
  119.        
  120.         OpenSPCoop2SoapMessage soapMessage = null;
  121.         try {
  122.             soapMessage = msg.castAsSoap();
  123.         }catch(Exception e) {
  124.             throw new ProtocolException(e.getMessage(),e);
  125.         }
  126.        
  127.         String correlationIdName = this.modiProperties.getSoapCorrelationIdName();
  128.         String correlationId = ModIUtilities.getSOAPHeaderCorrelationIdValue(soapMessage, bufferMessageReadOnly, idTransazione);
  129.        
  130.         String replyToName = this.modiProperties.getSoapReplyToName();
  131.         String replyToAddress = ModIUtilities.getSOAPHeaderReplyToValue(soapMessage, bufferMessageReadOnly, idTransazione);

  132.        
  133.         if(replyToAddress!=null) {
  134.             busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE_ASINCRONA_REPLY_TO, replyToAddress);
  135.         }
  136.         if(correlationId!=null) {
  137.             busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE_ASINCRONA_ID_CORRELAZIONE, correlationId);
  138.             if(correlationId.length()<=255) {
  139.                 busta.setCollaborazione(correlationId);
  140.             }
  141.         }
  142.        
  143.         if(asyncInteractionType!=null) {
  144.             if(ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_VALUE_PUSH.equals(asyncInteractionType)) {
  145.                 if(ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_RUOLO_VALUE_RICHIESTA.equals(asyncInteractionRole)) {
  146.                     if(request) {
  147.                         if(replyToAddress==null || "".equals(replyToAddress)) {
  148.                             erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SERVIZIO_CORRELATO_NON_PRESENTE,
  149.                                     getErrorHeaderSoapNonPresente(replyToName)));
  150.                         }
  151.                         if(this.modiProperties.isSoapSecurityTokenPushReplyToUpdateInErogazione()) {
  152.                             ModIUtilities.addSOAPHeaderReplyTo(soapMessage, bufferMessageReadOnly, idTransazione, replyTo); // aggiorna il valore se giĆ  esistente
  153.                         }
  154.                     }
  155.                     else {
  156.                         if(correlationId==null || "".equals(correlationId)) {
  157.                             erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.COLLABORAZIONE_NON_PRESENTE,
  158.                                     getErrorHeaderSoapNonPresente(correlationIdName)));
  159.                         }
  160.                     }
  161.                 }
  162.                 else {
  163.                     if(request &&
  164.                         (correlationId==null || "".equals(correlationId))
  165.                         ){
  166.                         erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.COLLABORAZIONE_NON_PRESENTE,
  167.                                 getErrorHeaderSoapNonPresente(correlationIdName)));
  168.                     }
  169.                 }
  170.             }
  171.             else {
  172.                 // pull
  173.                 if(request) {
  174.                    
  175.                     // Flusso di richiesta
  176.                    
  177.                     if(
  178.                             (
  179.                                     ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_RUOLO_VALUE_RICHIESTA_STATO.equals(asyncInteractionRole)
  180.                                     ||
  181.                                     ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_RUOLO_VALUE_RISPOSTA.equals(asyncInteractionRole)
  182.                             )
  183.                             &&
  184.                             (correlationId==null || "".equals(correlationId))
  185.                         ){
  186.                         erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.COLLABORAZIONE_NON_PRESENTE,
  187.                                 getErrorHeaderSoapNonPresente(correlationIdName)));
  188.                     }
  189.                    
  190.                    
  191.                 }
  192.                 else {
  193.                    
  194.                     // Flusso di risposta
  195.                    
  196.                     if(ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_RUOLO_VALUE_RICHIESTA.equals(asyncInteractionRole) &&
  197.                         (correlationId==null || "".equals(correlationId))
  198.                     ){
  199.                         erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.COLLABORAZIONE_NON_PRESENTE,
  200.                                 getErrorHeaderSoapNonPresente(correlationIdName)));
  201.                     }
  202.                    
  203.                 }
  204.             }
  205.         }
  206.        
  207.     }
  208.    
  209.     public SOAPEnvelope validateSecurityProfile(OpenSPCoop2Message msg, boolean request, String securityMessageProfile, boolean corniceSicurezza, boolean includiRequestDigest, boolean signAttachments,
  210.             Busta busta, List<Eccezione> erroriValidazione,
  211.             ModITruststoreConfig trustStoreCertificati, ModISecurityConfig securityConfig,
  212.             boolean buildSecurityTokenInRequest,
  213.             Map<String, Object> dynamicMapParameter, Busta datiRichiesta, RequestInfo requestInfo, MsgDiagnostico msgDiag) throws ProtocolException {
  214.        
  215.         if(msg==null) {
  216.             throw new ProtocolException("Param msg is null");
  217.         }
  218.        
  219.         MessageSecurityContextParameters messageSecurityContextParameters = new MessageSecurityContextParameters();
  220.         messageSecurityContextParameters.setFunctionAsClient(false);
  221.         messageSecurityContextParameters.setPrefixWsuId(OpenSPCoop2Properties.getInstance().getPrefixWsuId()); // NOTA: deve essere lo stesso di govway usato in altri profili
  222.         MessageSecurityContext messageSecurityContext = new MessageSecurityContext_impl(messageSecurityContextParameters);
  223.        
  224.         boolean attesoSecurityHeader = true;
  225.         if(!request) {
  226.             try {
  227.                 if(msg.isFault()) {
  228.                     attesoSecurityHeader = false;
  229.                 }
  230.             }catch(Exception e) {
  231.                 throw new ProtocolException(e.getMessage(),e);
  232.             }
  233.         }
  234.        
  235.         boolean bufferMessageReadOnly = this.modiProperties.isValidazioneBufferEnabled();
  236.         String idTransazione = null;
  237.         if(this.context!=null) {
  238.             idTransazione = (String)this.context.getObject(org.openspcoop2.core.constants.Costanti.ID_TRANSAZIONE);
  239.         }
  240.        
  241.                
  242.         if(!messageSecurityContext.existsSecurityHeader(msg, this.modiProperties.getSoapSecurityTokenActor(),
  243.                 bufferMessageReadOnly, idTransazione)){
  244.             if(attesoSecurityHeader) {
  245.                 erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_NON_PRESENTE,
  246.                         "Header Message Security non riscontrato nella SOAPEnvelope ricevuta"));
  247.             }
  248.             return null;
  249.         }
  250.        
  251.         OpenSPCoop2SoapMessage soapMessage = null;
  252.         try {
  253.             soapMessage = msg.castAsSoap();
  254.         }catch(Exception e) {
  255.             throw new ProtocolException(e.getMessage(),e);
  256.         }
  257.         SOAPInfo soapInfo = new SOAPInfo();
  258.         boolean useSoapReader = false; // i riferimenti recuperati (header, requestDigestHeader, wsAddressing vengono salvati nel contesto per poi eliminarli successivamente)
  259.         try {
  260.             soapInfo.read(useSoapReader, soapMessage, bufferMessageReadOnly, idTransazione, true, true, false);
  261.         }catch(Exception e) {
  262.             throw new ProtocolException(e.getMessage(),e);
  263.         }
  264.        
  265.         boolean filtroDuplicati = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM02.equals(securityMessageProfile) ||
  266.                 ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0302.equals(securityMessageProfile) ||
  267.                 ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile);
  268.        
  269.         boolean integritaX5c = false;
  270.         if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0301.equals(securityMessageProfile) ||
  271.                 ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0302.equals(securityMessageProfile)) {
  272.             integritaX5c = true;
  273.         }
  274.         boolean integritaKid = false;
  275.         if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile) ||
  276.                 ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile)) {
  277.             integritaKid = true;
  278.         }
  279.         boolean integrita = integritaX5c || integritaKid;
  280.        
  281.         if(integritaKid) {
  282.             String labelPattern = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile) ?
  283.                     CostantiLabel.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_LABEL_IDAM0401_REST :
  284.                     CostantiLabel.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_LABEL_IDAM0402_REST;
  285.             throw new ProtocolException("Sicurezza Messaggio con pattern '"+labelPattern+"' non utilizzabile su API SOAP");
  286.         }

  287.         /*
  288.          * == requestDigest ==
  289.          */
  290.        
  291.         SOAPHeaderElement requestDigestHeader = null;
  292.         if(integrita && !request && includiRequestDigest) {
  293.             requestDigestHeader = ModIUtilities.getSOAPHeaderRequestDigest(useSoapReader, soapMessage, bufferMessageReadOnly, idTransazione);
  294.         }
  295.        
  296.        
  297.         /*
  298.          * == signature ==
  299.          */
  300.        
  301.         X509Certificate x509 = null;
  302.         List<Reference> elementsToClean = null;
  303.         SOAPHeaderElement securityHeader = null;
  304.         Timestamp timestamp = null;
  305.         WSDataRef timestamptRef = null;
  306.         WSDataRef wsaToRef = null;
  307.         WSDataRef wsaMessageIdRef = null;
  308.         WSDataRef bodyRef = null;
  309.         WSDataRef requestDigestRef = null;
  310.         List<WSDataRef> attachmentsRef = new ArrayList<>();
  311.         MessageSecurityReceiver_wss4j wss4jSignature = null;
  312.         try {
  313.        
  314.             wss4jSignature = new MessageSecurityReceiver_wss4j();
  315.             Map<String,Object> secProperties = new HashMap<>();
  316.             secProperties.put(SecurityConstants.SECURITY_ENGINE, SecurityConstants.SECURITY_ENGINE_WSS4J);
  317.             if(this.modiProperties.getSoapSecurityTokenActor()!=null && !"".equals(this.modiProperties.getSoapSecurityTokenActor())) {
  318.                 secProperties.put(SecurityConstants.ACTOR, this.modiProperties.getSoapSecurityTokenActor());
  319.             }
  320.             secProperties.put(SecurityConstants.MUST_UNDERSTAND, this.modiProperties.isSoapSecurityTokenMustUnderstand()+"");
  321.            
  322.             // cornice sicurezza
  323.             if(!request) {
  324.                 corniceSicurezza = false; // permessa solo per i messaggi di richiesta
  325.             }
  326.             if(corniceSicurezza) {
  327.                 addValidationCorniceSicurezza(secProperties);
  328.             }
  329.            
  330.             // action
  331.             StringBuilder bfAction = new StringBuilder();
  332.             bfAction.append(SecurityConstants.TIMESTAMP_ACTION).append(" ").append(SecurityConstants.SIGNATURE_ACTION);
  333.             if(corniceSicurezza) {
  334.                 bfAction.append(" ").append(SecurityConstants.ACTION_SAML_TOKEN_UNSIGNED);
  335.             }
  336.             secProperties.put(SecurityConstants.ACTION, bfAction.toString());
  337.                        
  338.             // parti attese come firmate
  339.             // La funzionalitĆ  solleva errori se trova anche altre parti firmate non attese.
  340.             // Implemento questo controllo tramite i WSDataRef
  341.             /**
  342.             StringBuilder bf = new StringBuilder();
  343.             bf.append("{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp");
  344.             bf.append(";");
  345.             bf.append("{Element}{").append(Costanti.WSA_NAMESPACE).append("}").append(Costanti.WSA_SOAP_HEADER_TO);
  346.             if(filtroDuplicati) {
  347.                 bf.append(";");
  348.                 bf.append("{Element}{").append(Costanti.WSA_NAMESPACE).append("}").append(Costanti.WSA_SOAP_HEADER_ID);
  349.             }
  350.             if(integrita) {
  351.                 bf.append(";");
  352.                 bf.append("{Element}{").append(soapEnvelope.getNamespaceURI()).append("}Body");
  353.                 if(signAttachments) {
  354.                     if(bf.length()>0) {
  355.                         bf.append(";");
  356.                     }
  357.                     bf.append("{}"+SecurityConstants.CID_ATTACH_WSS4j);
  358.                 }
  359.             }
  360.             if(addCorniceSicurezza) {
  361.                 bf.append(";");
  362.                 bf.append("{Element}{").append(Costanti.SAML_20_NAMESPACE).append("}Assertion");
  363.             }
  364.             secProperties.put(SecurityConstants.SIGNATURE_PARTS, bf.toString());
  365.             secProperties.put(SecurityConstants.SIGNATURE_PARTS_VERIFY, SecurityConstants.TRUE);
  366.             */
  367.            
  368.             // truststore
  369.             Properties pTruststore = new Properties();
  370.             /**pTruststore.put(KeystoreConstants.PROPERTY_PROVIDER, KeystoreConstants.PROVIDER_DEFAULT);*/
  371.             pTruststore.put(KeystoreConstants.PROPERTY_PROVIDER, KeystoreConstants.PROVIDER_GOVWAY);
  372.             pTruststore.put(KeystoreConstants.PROPERTY_TRUSTSTORE_TYPE, trustStoreCertificati.getSecurityMessageTruststoreType());
  373.             if(trustStoreCertificati.getSecurityMessageTruststorePassword()!=null) {
  374.                 pTruststore.put(KeystoreConstants.PROPERTY_TRUSTSTORE_PASSWORD, trustStoreCertificati.getSecurityMessageTruststorePassword());
  375.             }
  376.             pTruststore.put(KeystoreConstants.PROPERTY_TRUSTSTORE_PATH, trustStoreCertificati.getSecurityMessageTruststorePath());
  377.             pTruststore.put(KeystoreConstants.PROPERTY_REQUEST_INFO, requestInfo);
  378.             if(trustStoreCertificati.getSecurityMessageTruststoreCRLs()!=null) {
  379.                 pTruststore.put(KeystoreConstants.PROPERTY_CRL, trustStoreCertificati.getSecurityMessageTruststoreCRLs());
  380.                 secProperties.put(SecurityConstants.ENABLE_REVOCATION, SecurityConstants.TRUE);
  381.             }
  382.             if(trustStoreCertificati.getSecurityMessageTruststoreOCSPPolicy()!=null) {
  383.                 secProperties.put(SecurityConstants.SIGNATURE_OCSP, trustStoreCertificati.getSecurityMessageTruststoreOCSPPolicy());
  384.                 if(trustStoreCertificati.getSecurityMessageTruststoreCRLs()!=null) {
  385.                     secProperties.put(SecurityConstants.SIGNATURE_CRL, trustStoreCertificati.getSecurityMessageTruststoreCRLs());
  386.                 }
  387.             }
  388.             secProperties.put(SecurityConstants.SIGNATURE_VERIFICATION_PROPERTY_REF_ID, pTruststore);
  389.             if(corniceSicurezza) {
  390.                 secProperties.put(SecurityConstants.SIGNATURE_PROPERTY_REF_ID, pTruststore);
  391.             }
  392.             secProperties.put(SecurityConstants.IS_BSP_COMPLIANT, SecurityConstants.TRUE);
  393.            
  394.            
  395.             //  ** Timestamp **
  396.             Long timeToLive = this.modiProperties.getSoapSecurityTokenTimestampCreatedTimeCheckMilliseconds(); // viene usato per vedere la data di creazione quanto si discosta da adesso
  397.             if(securityConfig.getCheckTtlIatMilliseconds()!=null) {
  398.                 timeToLive = securityConfig.getCheckTtlIatMilliseconds();
  399.             }
  400.             boolean setTimeToLive = false;
  401.             if(timeToLive!=null &&
  402.                 msg!=null) {
  403.                 msg.addContextProperty(ModICostanti.MODIPA_OPENSPCOOP2_MSG_CONTEXT_IAT_TTL_CHECK, timeToLive);
  404.                 // Non imposto il valore qua, ma inseriro un valoro alto (3650 giorni) in modo che la libreria non effettui il controllo, che invece avviene nella validazione semantica
  405.                 // In modo da uniformare l'errore rispetto anche a REST
  406.                 /**
  407.                 int value = timeToLive.intValue();
  408.                 if(value>=1000) {
  409.                     value = value / 1000; // riporto in secondi
  410.                     secProperties.put(SecurityConstants.TIMESTAMP_TTL, value+"");
  411.                     set_TimeToLive = true;
  412.                 }*/
  413.             }
  414.             if(!setTimeToLive) {
  415.                 // devo impostare un valore alto, altrimenti il default di wss4j e' 60 secondi
  416.                 // 3650 giorni (60s * 60m * 24h * 3650 giorni = 315360000)
  417.                 secProperties.put(SecurityConstants.TIMESTAMP_TTL, 315360000+"");
  418.             }
  419.            
  420.             Long futureTimeToLive = this.modiProperties.getSoapSecurityTokenTimestampCreatedTimeCheckFutureToleranceMilliseconds();
  421.             if(futureTimeToLive!=null) {
  422.                 // Non imposto il valore qua, in modo che la libreria non effettui il controllo, che invece avviene nella validazione semantica
  423.                 /**
  424.                 long value = futureTimeToLive.longValue();
  425.                 if(value>=1000) {
  426.                     value = value / 1000l; // riporto in secondi
  427.                     secProperties.put(SecurityConstants.TIMESTAMP_FUTURE_TTL, value+"");
  428.                 }
  429.                 */
  430.             }
  431.            
  432.             // disabilito qua la validazione, in modo da implementarla sulla validazione semantica
  433.             // In modo da uniformare l'errore rispetto anche a REST
  434.             secProperties.put(SecurityConstants.TIMESTAMP_STRICT, false+"");
  435.            
  436.            
  437.             // setProperties
  438.             messageSecurityContext.setIncomingProperties(secProperties, false);
  439.             if(signAttachments) {
  440.                 messageSecurityContext.setManualAttachmentsSignaturePart("{}"+SecurityConstants.CID_ATTACH_WSS4J);
  441.             }
  442.            
  443.            
  444.             // ** Raccolgo elementi "toccati" da Security per pulirli poi in fase di sbustamento ** /
  445.             elementsToClean = wss4jSignature.getDirtyElements(messageSecurityContext, soapMessage);
  446.            
  447.            
  448.             // ** Verifica firma elementi richiesti dalla configurazione ** /
  449.             List<SubErrorCodeSecurity> listaErroriRiscontrati = new ArrayList<>();
  450.             wss4jSignature.checkEncryptSignatureParts(messageSecurityContext,elementsToClean, soapMessage,listaErroriRiscontrati);
  451.             if(!listaErroriRiscontrati.isEmpty()){
  452.                 StringBuilder bf = new StringBuilder();
  453.                 for (Iterator<?> iterator = listaErroriRiscontrati.iterator(); iterator.hasNext();) {
  454.                     SubErrorCodeSecurity subCodiceErroreSicurezza = (SubErrorCodeSecurity) iterator.next();
  455.                     if(bf.length()>0){
  456.                         bf.append(" ; ");
  457.                     }
  458.                     bf.append(subCodiceErroreSicurezza.getMsgErrore());
  459.                 }
  460.                 erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_NON_PRESENTE,
  461.                         bf.toString()));
  462.                 return null;
  463.             }
  464.            
  465.            
  466.             // ** Applico sicurezza tramite engine **/
  467.             wss4jSignature.process(messageSecurityContext, soapMessage, busta,
  468.                     bufferMessageReadOnly, idTransazione, this.context);
  469.            
  470.            
  471.             // ** Leggo certificato client **/
  472.             x509 = wss4jSignature.getX509Certificate();
  473.        
  474.            
  475.             // ** Leggo security header **/
  476.             securityHeader = messageSecurityContext.getSecurityHeader(msg, this.modiProperties.getSoapSecurityTokenActor(),
  477.                     bufferMessageReadOnly, idTransazione);
  478.             timestamp = wss4jSignature.getTimestamp();
  479.             List<WSDataRef> signatureRefs = wss4jSignature.getSignatureRefs();  
  480.             if(signatureRefs!=null && !signatureRefs.isEmpty()) {
  481.                 for (WSDataRef wsDataRef : signatureRefs) {
  482.                    
  483.                     if(wsDataRef.getName()!=null && wsDataRef.getName().getLocalPart()!=null && wsDataRef.getName().getNamespaceURI()!=null) {
  484.                         busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_SIGNED_SOAP_PREFIX+wsDataRef.getName().getLocalPart(), wsDataRef.getName().getNamespaceURI());
  485.                     }
  486.                    
  487.                     if(wsDataRef.getName()!=null &&
  488.                             "Timestamp".equals(wsDataRef.getName().getLocalPart()) &&
  489.                             "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd".equals(wsDataRef.getName().getNamespaceURI())) {
  490.                         timestamptRef = wsDataRef;
  491.                     }
  492.                     else if(wsDataRef.getName()!=null &&
  493.                             Costanti.WSA_SOAP_HEADER_TO.equals(wsDataRef.getName().getLocalPart()) &&
  494.                             Costanti.WSA_NAMESPACE.equals(wsDataRef.getName().getNamespaceURI())) {
  495.                         wsaToRef = wsDataRef;
  496.                     }
  497.                     else if(wsDataRef.getName()!=null &&
  498.                             Costanti.WSA_SOAP_HEADER_ID.equals(wsDataRef.getName().getLocalPart()) &&
  499.                             Costanti.WSA_NAMESPACE.equals(wsDataRef.getName().getNamespaceURI())) {
  500.                         wsaMessageIdRef = wsDataRef;
  501.                     }
  502.                     else if(wsDataRef.getName()!=null &&
  503.                             "Body".equals(wsDataRef.getName().getLocalPart()) &&
  504.                             soapInfo.getEnvelopeNamespace().equals(wsDataRef.getName().getNamespaceURI())) {
  505.                         bodyRef = wsDataRef;
  506.                     }
  507.                     else if(requestDigestHeader!=null &&
  508.                             wsDataRef.getName()!=null &&
  509.                             requestDigestHeader.getLocalName().equals(wsDataRef.getName().getLocalPart()) &&
  510.                             requestDigestHeader.getNamespaceURI().equals(wsDataRef.getName().getNamespaceURI())) {
  511.                         requestDigestRef = wsDataRef;
  512.                     }
  513.                     else if(wsDataRef.getName()!=null &&
  514.                             "attachment".equals(wsDataRef.getName().getLocalPart()) &&
  515.                             WSSAttachmentsConstants.SWA_NS.equals(wsDataRef.getName().getNamespaceURI())) {
  516.                         attachmentsRef.add(wsDataRef);
  517.                     }
  518. /**                 else {
  519. //                      System.out.println("TROVATO ALTRO WS DATA Name["+wsDataRef.getName()+"] wsuId["+wsDataRef.getWsuId()+"]");
  520. //                  }*/
  521.                 }
  522.             }
  523.            
  524.         }catch(Exception e) {
  525.             this.logError("Errore durante la validazione del token di sicurezza: "+e.getMessage(),e);
  526.             erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_NON_VALIDA,
  527.                     e.getMessage(),e));
  528.             return null;
  529.         }
  530.        
  531.                
  532.         if(x509==null || x509.getSubjectX500Principal()==null) {
  533.             erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(
  534.                     request ? CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_FRUITORE_NON_PRESENTE :
  535.                         CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_EROGATORE_NON_PRESENTE,
  536.                     "Certificato X509 mittente non presente"));
  537.         }
  538.         else {
  539.             busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_X509_SUBJECT, x509.getSubjectX500Principal().toString());
  540.             if(x509.getIssuerX500Principal()!=null) {
  541.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_X509_ISSUER, x509.getIssuerX500Principal().toString());
  542.             }
  543.            
  544.             if(request) {
  545.                 if(msg==null || msg.getTransportRequestContext()==null || msg.getTransportRequestContext().getInterfaceName()==null) {
  546.                     throw new ProtocolException("ID Porta non presente");
  547.                 }
  548.                 IDPortaApplicativa idPA = new IDPortaApplicativa();
  549.                 idPA.setNome(msg.getTransportRequestContext().getInterfaceName());
  550.                 PortaApplicativa pa = null;
  551.                 try {
  552.                     pa = this.factory.getCachedConfigIntegrationReader(this.state, this.requestInfo).getPortaApplicativa(idPA);
  553.                 }catch(Exception e) {
  554.                     throw new ProtocolException(e.getMessage(),e);
  555.                 }
  556.                 boolean autenticazioneToken = pa!=null && pa.getGestioneToken()!=null && pa.getGestioneToken().getPolicy()!=null && StringUtils.isNotEmpty(pa.getGestioneToken().getPolicy());
  557.                 if(autenticazioneToken) {
  558.                     // l'autenticazione dell'applicativo mittente avviene per token
  559.                     // Il token rappresenta un integrity
  560.                 }
  561.                 else {
  562.                     identificazioneApplicativoMittente(x509,msg,busta,msgDiag);
  563.                 }
  564.             }
  565.         }
  566.        
  567.         SoapMessageSecurityToken soapSecurityToken = null;
  568.         if(request && this.context!=null) {
  569.            
  570.             SecurityToken securityTokenForContext = ModIUtilities.newSecurityToken(this.context);
  571.            
  572.             soapSecurityToken = new SoapMessageSecurityToken();
  573.             soapSecurityToken.setCertificate(new CertificateInfo(x509, "soapEnvelope"));
  574.             //soapSecurityToken.setToken(token); // imposto in fondo a questo metodo        
  575.             securityTokenForContext.setEnvelope(soapSecurityToken);
  576.            
  577.         }
  578.        
  579.         // NOTA: Inizializzare da qua il dynamicMap altrimenti non ci finisce l'identificazione del mittente effettuata dal metodo sopra 'identificazioneApplicativoMittente'
  580.         Map<String, Object> dynamicMap = null;
  581.         Map<String, Object> dynamicMapRequest = null;
  582.         if(!request) {
  583.             dynamicMapRequest = ModIUtilities.removeDynamicMapRequest(this.context);
  584.         }
  585.         try {
  586.             if(dynamicMapRequest!=null) {
  587.                 dynamicMap = DynamicUtils.buildDynamicMapResponse(msg, this.context, null, this.log, bufferMessageReadOnly, dynamicMapRequest);
  588.             }
  589.             else {
  590.                 dynamicMap = DynamicUtils.buildDynamicMap(msg, this.context, datiRichiesta, this.log, bufferMessageReadOnly);
  591.                 ModIUtilities.saveDynamicMapRequest(this.context, dynamicMap);
  592.             }
  593.         }catch(Exception e) {
  594.             throw new ProtocolException(e.getMessage(),e);
  595.         }
  596.         if(dynamicMapParameter!=null && dynamicMap!=null) {
  597.             dynamicMapParameter.putAll(dynamicMap);
  598.         }
  599.        
  600.    
  601.         if(timestamp==null) {
  602.             erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.ORA_REGISTRAZIONE_NON_PRESENTE,
  603.                     "Header WSSecurity Timestamp"));
  604.         }
  605.         else {
  606.            
  607.             if(timestamptRef==null || timestamptRef.getDigestValue()==null || timestamptRef.getDigestAlgorithm()==null) {
  608.                 erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.ORA_REGISTRAZIONE_NON_VALIDA,
  609.                         "Header WSSecurity Timestamp non firmato"));
  610.             }
  611.             else {
  612.                
  613.                 if(timestamp.getCreated()!=null) {
  614.                     long ms = timestamp.getCreated().toEpochMilli();
  615.                     Date d = new Date(ms); // la conversione serve a risolvere il timezone
  616.                     busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_IAT, DateUtils.getSimpleDateFormatMs().format(d));
  617.                 }
  618.                 else {
  619.                     erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.ORA_REGISTRAZIONE_NON_PRESENTE,
  620.                             "Header WSSecurity Timestamp; elemento 'Created'"));
  621.                 }
  622.                 if(timestamp.getExpires()!=null) {
  623.                     long ms = timestamp.getExpires().toEpochMilli();
  624.                     Date d = new Date(ms); // la conversione serve a risolvere il timezone
  625.                     busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_EXP, DateUtils.getSimpleDateFormatMs().format(d));
  626.                 }
  627.                 else {
  628.                     erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SCADENZA_NON_PRESENTE,
  629.                             "Header WSSecurity Timestamp; elemento 'Expires'"));
  630.                 }
  631.                
  632.             }
  633.            
  634.         }
  635.        
  636.        
  637.         if(integrita) {
  638.             if(bodyRef==null || bodyRef.getDigestValue()==null || bodyRef.getDigestAlgorithm()==null) {
  639.                 erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.PROFILO_TRASMISSIONE_NON_VALIDO,
  640.                         "Header WSSecurity Signature; SOAP Body non firmato"));
  641.             }
  642.             else {
  643.                 SignatureDigestAlgorithm s = SignatureDigestAlgorithm.toEnumConstant(bodyRef.getDigestAlgorithm());
  644.                 String digestValue = s!=null ? (s.name()+"=") : "";
  645.                 /**System.out.println("In Hex: "+org.apache.commons.codec.binary.Hex.encodeHexString(bodyRef.getDigestValue()));*/
  646.                 digestValue = digestValue + Base64Utilities.encodeAsString(bodyRef.getDigestValue());
  647.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_DIGEST, digestValue);
  648.                
  649.                 if(request && includiRequestDigest && this.context!=null && securityHeader!=null) {
  650.                    
  651.                     String digestNamespace = "http://www.w3.org/2000/09/xmldsig#";
  652.                     String digestReferencePattern = "//{"+digestNamespace+"}:Reference";
  653.                     OpenSPCoop2MessageFactory messageFactory = msg!=null ? msg.getFactory() : OpenSPCoop2MessageFactory.getDefaultMessageFactory();
  654.                     DynamicNamespaceContext dnc = MessageDynamicNamespaceContextFactory.getInstance(messageFactory).getNamespaceContext(securityHeader);
  655.                     XPathExpressionEngine xpathEngine = new XPathExpressionEngine(messageFactory);
  656.                    
  657.                     Object res = null;
  658.                     try {
  659.                         res = xpathEngine.getMatchPattern(securityHeader, dnc, digestReferencePattern, XPathReturnType.NODESET);
  660.                     }catch(XPathNotFoundException notFound) {
  661.                         // ignore
  662.                     }catch(Exception e) {
  663.                         throw new ProtocolException(e.getMessage(),e);
  664.                     }
  665.                     if(res!=null) {
  666.                         if(res instanceof NodeList) {
  667.                             NodeList nodeList = (NodeList) res;
  668.                             this.context.addObject(ModICostanti.MODIPA_CONTEXT_REQUEST_DIGEST, nodeList);
  669.                         }
  670.                         else {
  671.                             this.logError("Tipo non gestito ritornato dal xpath engine durante la raccolta delle signature references ["+res.getClass().getName()+"]");
  672.                         }
  673.                     }
  674.                 }
  675.             }
  676.            
  677.             if(!request && includiRequestDigest) {
  678.                 if(requestDigestHeader==null) {
  679.                     erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.PROFILO_TRASMISSIONE_NON_VALIDO,
  680.                             "Header Request Digest non presente"));
  681.                 }
  682.                 if(requestDigestRef==null || requestDigestRef.getDigestValue()==null || requestDigestRef.getDigestAlgorithm()==null) {
  683.                     erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.PROFILO_TRASMISSIONE_NON_VALIDO,
  684.                             "Header WSSecurity Signature; Header Request Digest non firmato"));
  685.                 }
  686.             }
  687.            
  688.             if(signAttachments) {
  689.                
  690.                 List<String> cidAttachments = new ArrayList<>();
  691.                 try {
  692.                     if(msg.castAsSoap().hasAttachments()){
  693.                         Iterator<?> itAttach = msg.castAsSoap().getAttachments();
  694.                         while (itAttach.hasNext()) {
  695.                             AttachmentPart ap = (AttachmentPart) itAttach.next();
  696.                             String contentId = normalizeContentID(ap.getContentId());
  697.                             cidAttachments.add(contentId);
  698.                             /**System.out.println("ADD '"+contentId+"'");*/
  699.                         }
  700.                     }
  701.                 }catch(Exception e) {
  702.                     throw new ProtocolException(e.getMessage(),e);
  703.                 }
  704.                
  705.                 if(attachmentsRef.isEmpty()) {
  706.                     if(requestDigestRef==null || requestDigestRef.getDigestValue()==null || requestDigestRef.getDigestAlgorithm()==null) {
  707.                         erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_ALLEGATO_NON_PRESENTE,
  708.                                 "Header WSSecurity Signature; Allegati non firmati"));
  709.                     }
  710.                 }
  711.                 else {
  712.                     for (WSDataRef wsDateRef : attachmentsRef) {
  713.                        
  714.                         String cid = null;
  715.                         String idLog = "";
  716.                         if(wsDateRef!=null) {
  717.                             cid = normalizeContentID(wsDateRef.getWsuId());
  718.                             idLog = (wsDateRef.getWsuId()!=null) ? " '"+cid+"'" : "";
  719.                         }
  720.                                                                        
  721.                         if(wsDateRef==null || wsDateRef.getDigestValue()==null || wsDateRef.getDigestAlgorithm()==null) {
  722.                             erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_ALLEGATO_NON_VALIDA,
  723.                                     "Header WSSecurity Signature; Allegato"+idLog+" non firmato (digest non presente)"));
  724.                         }
  725.                         if(cid==null) {
  726.                             erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_ALLEGATO_NON_VALIDA,
  727.                                     "Header WSSecurity Signature; Allegato"+idLog+" non firmato (cid non presente)"));
  728.                         }
  729.                         //System.out.println("CID FIRMATO '"+cid+"'");
  730.                        
  731.                         if(!cidAttachments.contains(cid)) {
  732.                             erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_ALLEGATO_NON_VALIDA,
  733.                                     "Header WSSecurity Signature; Allegato con id"+idLog+", riferito nella firma, non esiste"));
  734.                         }
  735.                         else {
  736.                             cidAttachments.remove(cid);
  737.                         }
  738.                     }
  739.                 }
  740.                
  741.                 if(!cidAttachments.isEmpty()) {
  742.                     for (String cid : cidAttachments) {
  743.                         erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_ALLEGATO_NON_VALIDA,
  744.                                 "Header WSSecurity Signature; Allegato"+cid+" non firmato"));
  745.                     }
  746.                 }
  747.                
  748.             }
  749.         }

  750.        
  751.        

  752.         /*
  753.          * == addressing ==
  754.          */
  755.         WSAddressingHeader wsAddressingHeader = null;
  756.         try {
  757.             WSAddressingUtilities wsaddressingUtilities = new WSAddressingUtilities(this.log);
  758.             wsAddressingHeader = wsaddressingUtilities.read(soapMessage, soapInfo.getHeader(), this.modiProperties.getSoapWSAddressingActor(), this.modiProperties.isSoapWSAddressingSchemaValidation());
  759.             if(wsAddressingHeader==null) {
  760.                 erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_INTESTAZIONE_NON_PRESENTE,
  761.                         "Header WSAddressing non presenti"));
  762.             }
  763.         }catch(Exception e) {
  764.             this.logError("Errore durante la letttura degli header WSAddressing: "+e.getMessage(),e);
  765.             erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_INTESTAZIONE_NON_PRESENTE,
  766.                     "Header WSAddressing; process failed: "+e.getMessage(),e));
  767.         }
  768.        
  769.         if(wsAddressingHeader!=null) {
  770.        
  771.             if(wsAddressingHeader.getTo()==null || wsAddressingHeader.getToValue()==null) {
  772.                 if(request || buildSecurityTokenInRequest) {
  773.                     erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(request ? CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_EROGATORE_NON_PRESENTE :
  774.                         CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_FRUITORE_NON_PRESENTE,
  775.                             "Header WSAddressing '"+Costanti.WSA_SOAP_HEADER_TO+"' non presente"));
  776.                 }
  777.             }
  778.             else {
  779.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_SOAP_WSA_TO, wsAddressingHeader.getToValue());
  780.                
  781.                 if(wsaToRef==null || wsaToRef.getDigestValue()==null || wsaToRef.getDigestAlgorithm()==null) {
  782.                     erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(request ? CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_EROGATORE_NON_VALIDO :
  783.                         CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_FRUITORE_NON_VALIDO,
  784.                         "Header WSAddressing '"+Costanti.WSA_SOAP_HEADER_TO+"' non firmato"));
  785.                 }
  786.             }
  787.            
  788.             if(wsAddressingHeader.getFrom()!=null && wsAddressingHeader.getFromValue()!=null) {
  789.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_SOAP_WSA_FROM, wsAddressingHeader.getFromValue());
  790.             }
  791.            
  792.             if(wsAddressingHeader.getId()==null || wsAddressingHeader.getIdValue()==null) {
  793.                 if(filtroDuplicati) {
  794.                     erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.IDENTIFICATIVO_MESSAGGIO_NON_PRESENTE,
  795.                         "Header WSAddressing '"+Costanti.WSA_SOAP_HEADER_ID+"' non presente"));
  796.                 }
  797.             }
  798.             else {
  799.                 String id = wsAddressingHeader.getIdValue();
  800.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_ID, id);
  801.                 if(id.length()<=255) {
  802.                     busta.setID(id);
  803.                 }
  804.                
  805.                 if(filtroDuplicati) {
  806.                     if(wsaMessageIdRef==null || wsaMessageIdRef.getDigestValue()==null || wsaMessageIdRef.getDigestAlgorithm()==null) {
  807.                         erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.IDENTIFICATIVO_MESSAGGIO_NON_VALIDO,
  808.                                 "Header WSAddressing '"+Costanti.WSA_SOAP_HEADER_ID+"' non firmato"));
  809.                     }
  810.                 }
  811.             }
  812.            
  813.             if(wsAddressingHeader.getRelatesTo()!=null && wsAddressingHeader.getRelatesToValue()!=null) {
  814.                 String relatesTo =  wsAddressingHeader.getRelatesToValue();
  815.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_RELATES_TO, relatesTo);
  816.                 if(relatesTo.length()<=255) {
  817.                     busta.setRiferimentoMessaggio(relatesTo);
  818.                 }
  819.             }

  820.         }
  821.         if(wsAddressingHeader==null) {
  822.             return null;
  823.         }
  824.        
  825.        
  826.         /*
  827.          * == cornice sicurezza ==
  828.          */
  829.         if(corniceSicurezza) {
  830.            
  831.             DynamicNamespaceContext dnc = MessageDynamicNamespaceContextFactory.getInstance(msg.getFactory()).getNamespaceContext(securityHeader);
  832.             XPathExpressionEngine engine = new XPathExpressionEngine(msg.getFactory());
  833.            
  834.             String xpathSaml2CodiceEnte = new StringBuilder().append("//{").append(org.openspcoop2.message.constants.Costanti.SAML_20_NAMESPACE).
  835.                     append("}NameID/text()").toString();
  836.             try {
  837.                 String codiceEnte = engine.getStringMatchPattern(securityHeader, dnc, xpathSaml2CodiceEnte);
  838.                 if(codiceEnte==null || "".equals(codiceEnte)) {
  839.                     throw new XPathNotFoundException("non trovato");
  840.                 }
  841.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_CORNICE_SICUREZZA_ENTE, codiceEnte);
  842.             }
  843.             catch(XPathNotFoundException notFound) {
  844.                 erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.MITTENTE_NON_PRESENTE,
  845.                         ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_LABEL+"; elemento 'Subject/NameID'"));
  846.             }catch(Exception e) {
  847.                 erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.MITTENTE_NON_VALIDO,
  848.                         ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_LABEL+"; elemento 'Subject/NameID'"));
  849.             }
  850.            
  851.             String attributeNameUser = this.modiProperties.getSicurezzaMessaggioCorniceSicurezzaSoapUser();
  852.             String xpathSaml2User = new StringBuilder().append("//{").append(org.openspcoop2.message.constants.Costanti.SAML_20_NAMESPACE).
  853.                     append("}Attribute[@Name='").append(attributeNameUser).append("']//{").
  854.                     append(org.openspcoop2.message.constants.Costanti.SAML_20_NAMESPACE).append("}AttributeValue/text()").toString();
  855.             try {
  856.                 String user = engine.getStringMatchPattern(securityHeader, dnc, xpathSaml2User);
  857.                 if(user==null || "".equals(user)) {
  858.                     throw new XPathNotFoundException("non trovato");
  859.                 }
  860.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_CORNICE_SICUREZZA_USER, user);
  861.             }
  862.             catch(XPathNotFoundException notFound) {
  863.                 erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.MITTENTE_NON_PRESENTE,
  864.                         ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_LABEL+"; elemento 'Attribute/"+attributeNameUser+"'"));
  865.             }catch(Exception e) {
  866.                 erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.MITTENTE_NON_VALIDO,
  867.                         ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_LABEL+"; elemento 'Attribute/"+attributeNameUser+"'"));
  868.             }
  869.            
  870.             String attributeNameIpUser = this.modiProperties.getSicurezzaMessaggioCorniceSicurezzaSoapIpuser();
  871.             String xpathSaml2IpUser = new StringBuilder().append("//{").append(org.openspcoop2.message.constants.Costanti.SAML_20_NAMESPACE).
  872.                     append("}Attribute[@Name='").append(attributeNameIpUser).append("']//{").
  873.                     append(org.openspcoop2.message.constants.Costanti.SAML_20_NAMESPACE).append("}AttributeValue/text()").toString();
  874.             try {
  875.                 String ipUser = engine.getStringMatchPattern(securityHeader, dnc, xpathSaml2IpUser);
  876.                 if(ipUser==null || "".equals(ipUser)) {
  877.                     throw new XPathNotFoundException("non trovato");
  878.                 }
  879.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_CORNICE_SICUREZZA_USER_IP, ipUser);
  880.             }
  881.             catch(XPathNotFoundException notFound) {
  882.                 erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.MITTENTE_NON_PRESENTE,
  883.                         ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_LABEL+"; elemento 'Attribute/"+attributeNameIpUser+"'"));
  884.             }catch(Exception e) {
  885.                 erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.MITTENTE_NON_VALIDO,
  886.                         ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_LABEL+"; elemento 'Attribute/"+attributeNameIpUser+"'"));
  887.             }
  888.            
  889.         }
  890.        
  891.        
  892.        
  893.         /*
  894.          * == sbustamento/traccia ==
  895.          */
  896.        
  897.         ModISOAPSecurity soapSecurity = new ModISOAPSecurity();
  898.        
  899.         // elementi per costruire la traccia
  900.         soapSecurity.setSecurityHeader(securityHeader);
  901.         soapSecurity.setWsAddressingHeader(wsAddressingHeader);
  902.         soapSecurity.setRequestDigestHeader(requestDigestHeader);
  903.         if(bodyRef!=null) {
  904.             soapSecurity.setWsuIdBodyRef(bodyRef.getWsuId());
  905.         }
  906.        
  907.         // elementi per lo sbustamento
  908.         soapSecurity.setElementsToClean(elementsToClean);
  909.         soapSecurity.setMessageSecurityContext(messageSecurityContext);
  910.         soapSecurity.setWss4jSignature(wss4jSignature);
  911.         msg.addContextProperty(ModICostanti.MODIPA_OPENSPCOOP2_MSG_CONTEXT_SBUSTAMENTO_SOAP, soapSecurity);
  912.        
  913.         try {
  914.             SOAPEnvelope soapEnvelope = soapSecurity.buildTraccia(msg.getMessageType());
  915.             if(soapSecurityToken!=null) {
  916.                 soapSecurityToken.setToken(soapEnvelope);
  917.             }
  918.             return soapEnvelope;
  919.         }catch(Exception e) {
  920.             throw new ProtocolException(e.getMessage(),e);
  921.         }
  922.        
  923.     }
  924.    
  925.     private String normalizeContentID(String contentId) {
  926.         if(contentId==null) {
  927.             return null;
  928.         }
  929.         contentId = contentId.replace("&lt;", "<");
  930.         contentId = contentId.replace("&gt;", ">");
  931.         if(contentId.startsWith("cid:") && contentId.length()>4){
  932.             contentId = contentId.substring(4);
  933.         }
  934.         if(contentId.startsWith("<") && contentId.length()>1)
  935.             contentId = contentId.substring(1);
  936.         if(contentId.endsWith(">") && contentId.length()>1)
  937.             contentId = contentId.substring(0,contentId.length()-1);
  938.         return contentId;
  939.     }
  940.    
  941.     private void addValidationCorniceSicurezza(Map<String,Object> secProperties) {

  942.         secProperties.put(SAMLBuilderConfigConstants.SAML_CONFIG_BUILDER_VERSION, SAMLBuilderConfigConstants.SAML_CONFIG_BUILDER_VERSION_20);
  943.         secProperties.put(SecurityConstants.SAML_ENVELOPED_SAML_SIGNATURE_XMLCONFIG_PREFIX_ID, SecurityConstants.TRUE);
  944.        
  945.         if(ModIImbustamentoSoap.isSenderVouche()) {
  946.             secProperties.put("validateSamlSubjectConfirmation", SecurityConstants.TRUE);
  947.             secProperties.put(SecurityConstants.SAML_SUBJECT_CONFIRMATION_VALIDATION_METHOD_XMLCONFIG_ID, SecurityConstants.SAML_SUBJECT_CONFIRMATION_VALIDATION_METHOD_XMLCONFIG_ID_SENDER_VOUCHES);
  948.         }
  949.         else {
  950.             secProperties.put("validateSamlSubjectConfirmation", SecurityConstants.FALSE);
  951.         }

  952.     }
  953. }