MessageSecurityContext.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.security.message;

  21. import java.io.IOException;
  22. import java.security.KeyStore;
  23. import java.util.ArrayList;
  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.security.auth.callback.Callback;
  30. import javax.security.auth.callback.CallbackHandler;
  31. import javax.security.auth.callback.UnsupportedCallbackException;
  32. import javax.xml.soap.SOAPElement;
  33. import javax.xml.soap.SOAPEnvelope;
  34. import javax.xml.soap.SOAPHeader;
  35. import javax.xml.soap.SOAPHeaderElement;
  36. import javax.xml.soap.SOAPPart;

  37. import org.apache.wss4j.common.ConfigurationConstants;
  38. import org.apache.wss4j.common.ext.WSPasswordCallback;
  39. import org.openspcoop2.core.commons.DBUtils;
  40. import org.openspcoop2.core.id.IDServizio;
  41. import org.openspcoop2.core.id.IDSoggetto;
  42. import org.openspcoop2.core.mvc.properties.utils.DBPropertiesUtils;
  43. import org.openspcoop2.core.mvc.properties.utils.MultiPropertiesUtilities;
  44. import org.openspcoop2.core.transazioni.utils.TempiElaborazione;
  45. import org.openspcoop2.message.MessageUtils;
  46. import org.openspcoop2.message.OpenSPCoop2Message;
  47. import org.openspcoop2.message.OpenSPCoop2MessageFactory;
  48. import org.openspcoop2.message.OpenSPCoop2SoapMessage;
  49. import org.openspcoop2.message.constants.MessageRole;
  50. import org.openspcoop2.message.constants.MessageType;
  51. import org.openspcoop2.message.constants.ServiceBinding;
  52. import org.openspcoop2.message.soap.SoapUtils;
  53. import org.openspcoop2.message.soap.reference.Reference;
  54. import org.openspcoop2.message.xml.XPathExpressionEngine;
  55. import org.openspcoop2.protocol.sdk.Busta;
  56. import org.openspcoop2.protocol.sdk.constants.CodiceErroreCooperazione;
  57. import org.openspcoop2.security.SecurityException;
  58. import org.openspcoop2.security.keystore.KeystoreConstants;
  59. import org.openspcoop2.security.message.constants.SecurityConstants;
  60. import org.openspcoop2.security.message.saml.SAMLConstants;
  61. import org.openspcoop2.security.message.utils.EncryptionBean;
  62. import org.openspcoop2.security.message.utils.SignatureBean;
  63. import org.openspcoop2.utils.LoggerWrapperFactory;
  64. import org.openspcoop2.utils.certificate.KeystoreType;
  65. import org.openspcoop2.utils.digest.IDigestReader;
  66. import org.openspcoop2.utils.properties.PropertiesUtilities;
  67. import org.openspcoop2.utils.resources.ClassLoaderUtilities;
  68. import org.openspcoop2.utils.xml.AbstractXPathExpressionEngine;
  69. import org.openspcoop2.utils.xml.DynamicNamespaceContext;
  70. import org.openspcoop2.utils.xml.XPathNotFoundException;
  71. import org.openspcoop2.utils.xml.XPathReturnType;
  72. import org.slf4j.Logger;

  73. /**
  74.  * Classe di base per la gestione della sicurezza
  75.  *
  76.  * @author Spadafora Marcello (Ma.Spadafora@finsiel.it)
  77.  * @author $Author$
  78.  * @version $Rev$, $Date$
  79.  */

  80. public abstract class MessageSecurityContext{
  81.    
  82.      
  83.     protected Map<String,Object> incomingProperties = new HashMap<>();
  84.     protected Map<String,Object> outgoingProperties = new HashMap<>();

  85.     protected boolean useActorDefaultIfNotDefined = true;
  86.     protected String actorDefault = null;
  87.     protected String actor;

  88.     protected String msgErrore;
  89.     protected CodiceErroreCooperazione codiceErrore;
  90.     /** Eventuale subCodici di errore */
  91.     protected List<SubErrorCodeSecurity> listaSubCodiceErrore = new ArrayList<>();
  92.        
  93.     protected boolean functionAsClient = true;
  94.    
  95.     protected String prefixWsuId;
  96.    
  97.     protected boolean removeAllWsuIdRef;
  98.    
  99.     protected String securityEngine;
  100.     protected IMessageSecurityContext messageSecurityContext;
  101.     protected IMessageSecuritySender messageSecuritySender;
  102.     protected IMessageSecurityReceiver messageSecurityReceiver;
  103.     protected IMessageSecurityDigest messageSecurityDigest;
  104.    
  105.     protected Logger log;
  106.     public Logger getLog() {
  107.         return this.log;
  108.     }

  109.     private IDSoggetto idFruitore;
  110.     private String pddFruitore;
  111.     private IDServizio idServizio;
  112.     private String pddErogatore;
  113.     public IDSoggetto getIdFruitore() {
  114.         return this.idFruitore;
  115.     }
  116.     public IDServizio getIdServizio() {
  117.         return this.idServizio;
  118.     }
  119.     public String getPddFruitore() {
  120.         return this.pddFruitore;
  121.     }
  122.     public String getPddErogatore() {
  123.         return this.pddErogatore;
  124.     }
  125.    
  126.     private List<Reference> references;
  127.     public List<Reference> getReferences() {
  128.         return this.references;
  129.     }
  130.     public void setReferences(List<Reference> references) {
  131.         this.references = references;
  132.     }
  133.    
  134.    
  135.     // I due encrypt part servono per un utilizzo manuale delle classi di sicurezza
  136.    
  137.     private String manualAttachmentsEncryptPart = null;
  138.     private String manualAttachmentsSignaturePart = null;
  139.    
  140.     public String getManualAttachmentsEncryptPart() {
  141.         return this.manualAttachmentsEncryptPart;
  142.     }
  143.     public void setManualAttachmentsEncryptPart(String manualAttachmentsEncryptPart) {
  144.         this.manualAttachmentsEncryptPart = manualAttachmentsEncryptPart;
  145.     }
  146.     public String getManualAttachmentsSignaturePart() {
  147.         return this.manualAttachmentsSignaturePart;
  148.     }
  149.     public void setManualAttachmentsSignaturePart(String manualAttachmentsSignaturePart) {
  150.         this.manualAttachmentsSignaturePart = manualAttachmentsSignaturePart;
  151.     }
  152.    
  153.     // I due bean signatureBean e encryptionBean servono per un utilizzo manuale delle classi di sicurezza.
  154.    
  155.     private SignatureBean signatureBean;
  156.     private EncryptionBean encryptionBean;
  157.     public SignatureBean getSignatureBean() {
  158.         return this.signatureBean;
  159.     }
  160.     public void setSignatureBean(SignatureBean signatureBean) {
  161.         this.signatureBean = signatureBean;
  162.     }
  163.     public EncryptionBean getEncryptionBean() {
  164.         return this.encryptionBean;
  165.     }
  166.     public void setEncryptionBean(EncryptionBean encryptionBean) {
  167.         this.encryptionBean = encryptionBean;
  168.     }
  169.    
  170.     /**
  171.      * Costruttore.
  172.      *
  173.      * @param messageSecurityContextParameters contextParameters
  174.      */
  175.     protected MessageSecurityContext(MessageSecurityContextParameters messageSecurityContextParameters){
  176.         this.useActorDefaultIfNotDefined = messageSecurityContextParameters.isUseActorDefaultIfNotDefined();
  177.         this.actorDefault = messageSecurityContextParameters.getActorDefault();
  178.         if(messageSecurityContextParameters.getLog()!=null)
  179.             this.log = messageSecurityContextParameters.getLog();
  180.         else
  181.             this.log = LoggerWrapperFactory.getLogger(MessageSecurityContext.class);
  182.         this.functionAsClient = messageSecurityContextParameters.isFunctionAsClient();
  183.         this.prefixWsuId = messageSecurityContextParameters.getPrefixWsuId();
  184.         this.removeAllWsuIdRef = messageSecurityContextParameters.isRemoveAllWsuIdRef();
  185.         this.idFruitore = messageSecurityContextParameters.getIdFruitore();
  186.         this.idServizio = messageSecurityContextParameters.getIdServizio();
  187.         this.pddFruitore = messageSecurityContextParameters.getPddFruitore();
  188.         this.pddErogatore = messageSecurityContextParameters.getPddErogatore();
  189.     }
  190.    
  191.    
  192.     /** Process */
  193.    
  194.     // incoming
  195.     protected abstract boolean processIncoming(OpenSPCoop2Message message, Busta busta, org.openspcoop2.utils.Map<Object> ctx);
  196.     public boolean processIncoming(OpenSPCoop2Message message, Busta busta, org.openspcoop2.utils.Map<Object> ctx, TempiElaborazione tempiElaborazione) {
  197.         MessageRole messageRole = message.getMessageRole();
  198.         if(MessageRole.REQUEST.equals(messageRole)) {
  199.             if(tempiElaborazione!=null) {
  200.                 tempiElaborazione.startSicurezzaMessaggioRichiesta();
  201.             }
  202.         }
  203.         else {
  204.             if(tempiElaborazione!=null) {
  205.                 tempiElaborazione.startSicurezzaMessaggioRisposta();
  206.             }
  207.         }
  208.         try {
  209.             return this.processIncoming(message, busta, ctx);
  210.         }
  211.         finally {
  212.             if(MessageRole.REQUEST.equals(messageRole)) {
  213.                 if(tempiElaborazione!=null) {
  214.                     tempiElaborazione.endSicurezzaMessaggioRichiesta();
  215.                 }
  216.             }
  217.             else {
  218.                 if(tempiElaborazione!=null) {
  219.                     tempiElaborazione.endSicurezzaMessaggioRisposta();
  220.                 }
  221.             }
  222.         }
  223.     }

  224.     // outcoming
  225.     protected abstract boolean processOutgoing(OpenSPCoop2Message message, org.openspcoop2.utils.Map<Object> ctx);
  226.     public boolean processOutgoing(OpenSPCoop2Message message, org.openspcoop2.utils.Map<Object> ctx, TempiElaborazione tempiElaborazione) {
  227.         MessageRole messageRole = message.getMessageRole();
  228.         if(MessageRole.REQUEST.equals(messageRole)) {
  229.             if(tempiElaborazione!=null) {
  230.                 tempiElaborazione.startSicurezzaMessaggioRichiesta();
  231.             }
  232.         }
  233.         else {
  234.             if(tempiElaborazione!=null) {
  235.                 tempiElaborazione.startSicurezzaMessaggioRisposta();
  236.             }
  237.         }
  238.         try {
  239.             return this.processOutgoing(message, ctx);
  240.         }
  241.         finally {
  242.             if(MessageRole.REQUEST.equals(messageRole)) {
  243.                 if(tempiElaborazione!=null) {
  244.                     tempiElaborazione.endSicurezzaMessaggioRichiesta();
  245.                 }
  246.             }
  247.             else {
  248.                 if(tempiElaborazione!=null) {
  249.                     tempiElaborazione.endSicurezzaMessaggioRisposta();
  250.                 }
  251.             }
  252.         }
  253.     }
  254.    

  255.     /** Function As Client */
  256.     public void setFunctionAsClient(boolean functionAsClient) {
  257.         this.functionAsClient = functionAsClient;
  258.     }
  259.     public boolean isFunctionAsClient() {
  260.         return this.functionAsClient;
  261.     }
  262.    
  263.    
  264.     /** Prefix WSUID */
  265.     public String getPrefixWsuId() {
  266.         return this.prefixWsuId;
  267.     }
  268.    

  269.     /**  indicazione se rimuovere tutti gli attributi WsuId negli elementi 'toccati' dalla sicurezza */
  270.     public boolean isRemoveAllWsuIdRef() {
  271.         return this.removeAllWsuIdRef;
  272.     }
  273.    
  274.    
  275.    
  276.     /** GetValues ottenuti dopo il processamento */
  277.     public abstract String getSubject();
  278.     public String getMsgErrore() { return this.msgErrore; }
  279.     public CodiceErroreCooperazione getCodiceErrore() { return this.codiceErrore; }
  280.     public List<SubErrorCodeSecurity> getListaSubCodiceErrore() {
  281.         return this.listaSubCodiceErrore;
  282.     }

  283.    
  284.    
  285.    
  286.     /** Actor utilizzato nell'header di sicurezza */
  287.     /**
  288.      * Set/get dell'Actor
  289.      */
  290.     public String getActor() {
  291.         return this.actor;
  292.     }
  293.     private void setActor(boolean incoming) {
  294.         boolean actorDefinito = false;
  295.         boolean mustUnderstandTrue=false;
  296.        
  297.         Map<String,Object> securityProperties = null;
  298.         if(incoming){
  299.             securityProperties = this.incomingProperties;
  300.         }else{
  301.             securityProperties = this.outgoingProperties;
  302.         }
  303.         if (securityProperties != null && securityProperties.size() > 0) {
  304.            
  305.             for (String key : securityProperties.keySet()) {
  306.                 String value = null;
  307.                 Object oValue = securityProperties.get(key);
  308.                 if(oValue instanceof String) {
  309.                     value = (String) oValue;
  310.                 }
  311.                
  312.                 /**System.out.println(key + " -> " + value );*/
  313.                 // check actor
  314.                 if(ConfigurationConstants.ACTOR.equals(key)){
  315.                     this.actor = value;
  316.                 }
  317.                
  318.                 // Check Fix Bug#18 Test-1
  319.                 if(ConfigurationConstants.MUST_UNDERSTAND.equals(key)){
  320.                     if("true".equals(value)){
  321.                         mustUnderstandTrue = true;
  322.                     }
  323.                 }else if("actor".equals(key)){
  324.                     actorDefinito = true;
  325.                 }
  326.                
  327.             }
  328.         }
  329.         if(mustUnderstandTrue && actorDefinito==false && this.useActorDefaultIfNotDefined ){
  330.             // Aggiungo actor 'govway'
  331.             this.actor = this.actorDefault;
  332.         }
  333.     }
  334.    
  335.    
  336.    
  337.     /** Security Message Properties */
  338.     /**
  339.      * Set/get  proprieta' che verranno usate per i messaggi in ingresso dal MessageSecurity
  340.      * @param secProperties
  341.      */
  342.     public void setIncomingProperties(Map<String,Object> secProperties) throws SecurityException{
  343.         this.setIncomingProperties(secProperties, true, false);
  344.     }
  345.     public void setIncomingProperties(Map<String,Object> secProperties, boolean convertSecProperties) throws SecurityException{
  346.         this.setIncomingProperties(secProperties, convertSecProperties, false);
  347.     }
  348.     public void setIncomingProperties(Map<String,Object> secProperties, boolean convertSecProperties, boolean preserveNotStringProperty) throws SecurityException{
  349.         if(secProperties!=null && secProperties.size()>0 && convertSecProperties) {
  350.             this.incomingProperties = convertSecProperties(secProperties, preserveNotStringProperty);
  351.         }
  352.         else {
  353.             this.incomingProperties = secProperties;
  354.         }
  355.         this.setActor(true);
  356.         this.readMessageSecurityEngine(true);
  357.         this.resolvePWCallback(true);
  358.     }
  359.     public Map<String,Object> getIncomingProperties() {
  360.         return this.incomingProperties;
  361.     }
  362.     /**
  363.      * Set/get  proprieta' che verranno usate per i messaggi in uscita dal MessageSecurity
  364.      * @param secProperties
  365.      */
  366.     public void setOutgoingProperties(Map<String,Object> secProperties) throws SecurityException{
  367.         this.setOutgoingProperties(secProperties, true, false);
  368.     }
  369.     public void setOutgoingProperties(Map<String,Object> secProperties, boolean convertSecProperties) throws SecurityException{
  370.         this.setOutgoingProperties(secProperties, convertSecProperties, false);
  371.     }
  372.     public void setOutgoingProperties(Map<String,Object> secProperties, boolean convertSecProperties, boolean preserveNotStringProperty) throws SecurityException{
  373.        
  374.         if(secProperties!=null && secProperties.size()>0 && convertSecProperties) {
  375.             this.outgoingProperties = convertSecProperties(secProperties, preserveNotStringProperty);
  376.         }
  377.         else {
  378.             this.outgoingProperties = secProperties;
  379.         }
  380.         this.setActor(false);
  381.         this.readMessageSecurityEngine(false);
  382.         this.resolvePWCallback(false);
  383.     }
  384.     public Map<String,Object> getOutgoingProperties() {
  385.         return this.outgoingProperties;
  386.     }
  387.    
  388.     private Map<String,Object> convertSecProperties(Map<String,Object> secProperties, boolean preserveNotStringProperty) throws SecurityException{
  389.        
  390.         try {
  391.        
  392.             Map<String, Object> mapNoStringProperty = new HashMap<>();
  393.            
  394.             Map<String, String> map = new HashMap<>();
  395.             if (secProperties != null && secProperties.size() > 0) {
  396.                
  397.                 for (String key : secProperties.keySet()) {
  398.                     Object value = secProperties.get(key);
  399.                     String v = null;
  400.                     if(value instanceof String) {
  401.                         v = (String) value;
  402.                     }
  403.                     map.put(key, v);
  404.                    
  405.                     if(preserveNotStringProperty &&
  406.                         value!=null && !(value instanceof String)) {
  407.                         mapNoStringProperty.put(key, value);
  408.                     }
  409.                 }
  410.             }
  411.            
  412.             Map<String, Properties> multiMap = DBPropertiesUtils.toMultiMap(map);
  413.            
  414.             Map<String, Object> table = new HashMap<>();
  415.            
  416.             Properties defaultProperties = MultiPropertiesUtilities.removeDefaultProperties(multiMap);
  417.             if(defaultProperties!=null && defaultProperties.size()>0) {
  418.                 Iterator<?> it = defaultProperties.keySet().iterator();
  419.                 while (it.hasNext()) {
  420.                     Object oKey = it.next();
  421.                     if(oKey instanceof String) {
  422.                         String key = (String) oKey;
  423.                         String value = null;
  424.                         Object oValue = defaultProperties.get(key);
  425.                         if(oValue instanceof String) {
  426.                             value = (String) oValue;
  427.                         }
  428.                         table.put(key, value);
  429.                     }
  430.                 }
  431.             }
  432.            
  433.             if(multiMap.size()>0) { // ho rimosso la mappa di default
  434.                
  435.                 if(preserveNotStringProperty && mapNoStringProperty.size()>0) {
  436.                    
  437.                     List<String> keysMultiMap = new ArrayList<>();
  438.                     keysMultiMap.addAll(multiMap.keySet());
  439.                    
  440.                     Iterator<String> it = mapNoStringProperty.keySet().iterator();
  441.                     while (it.hasNext()) {
  442.                         String keyWithPrefix = it.next();
  443.                         Object object = mapNoStringProperty.get(keyWithPrefix);
  444.                        
  445.                         String prefix = DBPropertiesUtils.startsWith(keysMultiMap, keyWithPrefix);  
  446.                         if(prefix==null) {
  447.                             table.put(keyWithPrefix, object);
  448.                         }
  449.                         else {
  450.                             String keyWithoutPrefix = DBPropertiesUtils.normalizePropertyName(prefix, keyWithPrefix);
  451.                             multiMap.get(prefix).put(keyWithoutPrefix, object);
  452.                         }
  453.                     }
  454.                    
  455.                 }
  456.                
  457.                 table.putAll(multiMap);
  458.                
  459.             }
  460.             else {
  461.                 if(preserveNotStringProperty && mapNoStringProperty.size()>0) {
  462.                     table.putAll(mapNoStringProperty);
  463.                 }
  464.             }
  465.            
  466.             return table;
  467.            
  468.         }catch(Exception e) {
  469.             throw new SecurityException(e.getMessage(),e);
  470.         }
  471.     }
  472.    
  473.    
  474.    
  475.     /** Message Security Engine */  
  476.     public String getSecurityEngine() {
  477.         return this.securityEngine;
  478.     }
  479.     public IMessageSecurityContext getMessageSecurityContext() {
  480.         return this.messageSecurityContext;
  481.     }
  482.     public IMessageSecuritySender getMessageSecuritySender() {
  483.         return this.messageSecuritySender;
  484.     }
  485.     public IMessageSecurityReceiver getMessageSecurityReceiver() {
  486.         return this.messageSecurityReceiver;
  487.     }
  488.     public IMessageSecurityDigest getMessageSecurityDigest() {
  489.         return this.messageSecurityDigest;
  490.     }
  491.     public IDigestReader getDigestReader(OpenSPCoop2MessageFactory messageFactory) throws SecurityException{
  492.         if(this.messageSecurityDigest!=null){
  493.             return this.getMessageSecurityDigest().getDigestReader(messageFactory, this);
  494.         }
  495.         return null;
  496.     }
  497.     private void readMessageSecurityEngine(boolean incoming) throws SecurityException{
  498.         try{
  499.            
  500.             this.securityEngine = SecurityConstants.SECURITY_ENGINE_WSS4J;
  501.             String engineProperty = null;
  502.             if(incoming){
  503.                 engineProperty = (String) this.incomingProperties.get(SecurityConstants.SECURITY_ENGINE);
  504.             }else{
  505.                 engineProperty = (String) this.outgoingProperties.get(SecurityConstants.SECURITY_ENGINE);
  506.             }
  507.             if(engineProperty!=null){
  508.                 engineProperty = engineProperty.trim();
  509.                 if(SecurityConstants.SECURITY_ENGINE_WSS4J.equals(engineProperty)){
  510.                     // DEFAULT: this.securityEngine = SecurityConstants.SECURITY_ENGINE_WSS4J;
  511.                 }
  512.                 else if(SecurityConstants.SECURITY_ENGINE_SOAPBOX.equals(engineProperty)){
  513.                     this.securityEngine = SecurityConstants.SECURITY_ENGINE_SOAPBOX;
  514.                 }
  515.                 else if(SecurityConstants.SECURITY_ENGINE_JOSE.equals(engineProperty)){
  516.                     this.securityEngine = SecurityConstants.SECURITY_ENGINE_JOSE;
  517.                 }
  518.                 else if(SecurityConstants.SECURITY_ENGINE_XML.equals(engineProperty)){
  519.                     this.securityEngine = SecurityConstants.SECURITY_ENGINE_XML;
  520.                 }
  521.                 else{
  522.                     throw new SecurityException("Security engine impostato ["+engineProperty+"] non supportato");
  523.                 }
  524.             }
  525.             if(SecurityConstants.SECURITY_ENGINE_WSS4J.equals(this.securityEngine)){
  526.                 this.messageSecurityContext = (IMessageSecurityContext) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.wss4j.MessageSecurityContext_wss4j");
  527.                 this.messageSecuritySender = (IMessageSecuritySender) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.wss4j.MessageSecuritySender_wss4j");
  528.                 this.messageSecurityReceiver = (IMessageSecurityReceiver) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.wss4j.MessageSecurityReceiver_wss4j");
  529.                 this.messageSecurityDigest = (IMessageSecurityDigest) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.wss4j.MessageSecurityDigest_wss4j");
  530.             }else if(SecurityConstants.SECURITY_ENGINE_SOAPBOX.equals(this.securityEngine)){
  531.                 this.messageSecurityContext = (IMessageSecurityContext) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.soapbox.MessageSecurityContext_soapbox");
  532.                 this.messageSecuritySender = (IMessageSecuritySender) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.soapbox.MessageSecuritySender_soapbox");
  533.                 this.messageSecurityReceiver = (IMessageSecurityReceiver) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.soapbox.MessageSecurityReceiver_soapbox");
  534.                 this.messageSecurityDigest = (IMessageSecurityDigest) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.soapbox.MessageSecurityDigest_soapbox");
  535.             }else if(SecurityConstants.SECURITY_ENGINE_JOSE.equals(this.securityEngine)){
  536.                 this.messageSecurityContext = (IMessageSecurityContext) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.jose.MessageSecurityContext_jose");
  537.                 this.messageSecuritySender = (IMessageSecuritySender) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.jose.MessageSecuritySender_jose");
  538.                 this.messageSecurityReceiver = (IMessageSecurityReceiver) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.jose.MessageSecurityReceiver_jose");
  539.                 this.messageSecurityDigest = (IMessageSecurityDigest) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.jose.MessageSecurityDigest_jose");
  540.             }else if(SecurityConstants.SECURITY_ENGINE_XML.equals(this.securityEngine)){
  541.                 this.messageSecurityContext = (IMessageSecurityContext) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.xml.MessageSecurityContext_xml");
  542.                 this.messageSecuritySender = (IMessageSecuritySender) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.xml.MessageSecuritySender_xml");
  543.                 this.messageSecurityReceiver = (IMessageSecurityReceiver) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.xml.MessageSecurityReceiver_xml");
  544.                 this.messageSecurityDigest = (IMessageSecurityDigest) ClassLoaderUtilities.newInstance("org.openspcoop2.security.message.xml.MessageSecurityDigest_xml");
  545.             }
  546.             this.messageSecurityContext.init(this);
  547.            
  548.         }catch(Exception e){
  549.             throw new SecurityException(e.getMessage(),e);
  550.         }
  551.     }
  552.    
  553.    
  554.    
  555.    
  556.        
  557.    
  558.     /** resolvePWCallback */
  559.     private void resolvePWCallback(boolean incoming) throws SecurityException{
  560.         try{
  561.             Map<String, Object> props = null;
  562.             if(incoming) {
  563.                 props = this.incomingProperties;
  564.             }else {
  565.                 props = this.outgoingProperties;
  566.             }
  567.            
  568.             boolean pwCallback = props.containsKey(SecurityConstants.PASSWORD_CALLBACK_REF); // non controllo il valore, mi basta la presenza
  569.             props.remove(SecurityConstants.PASSWORD_CALLBACK_REF);
  570.             if(pwCallback) {
  571.                
  572.                 String aliasGenerico = null;
  573.                 if(props.containsKey(SecurityConstants.USER)) {
  574.                     aliasGenerico = (String) props.get(SecurityConstants.USER);
  575.                 }  
  576.                
  577.                 HashMap<String, String> mapAliasToPassword = new HashMap<>();
  578.                
  579.                 if(props.containsKey(SecurityConstants.SIGNATURE_PASSWORD) ||
  580.                         !isPasswordRequired(props, SecurityConstants.SIGNATURE_PROPERTY_REF_ID) ) {
  581.                     String password = (String) props.get(SecurityConstants.SIGNATURE_PASSWORD);
  582.                     String alias = null;
  583.                     if(props.containsKey(SecurityConstants.SIGNATURE_USER)) {
  584.                         alias = (String) props.get(SecurityConstants.SIGNATURE_USER);
  585.                     }
  586.                     else {
  587.                         alias = aliasGenerico;
  588.                     }
  589.                     if(alias!=null){
  590.                         mapAliasToPassword.put(alias, password);
  591.                     }
  592.                 }
  593.                
  594.                 if(props.containsKey(SecurityConstants.ENCRYPTION_PASSWORD) ||
  595.                         !isPasswordRequired(props, SecurityConstants.ENCRYPTION_PROPERTY_REF_ID) ) {
  596.                     String password = (String) props.get(SecurityConstants.ENCRYPTION_PASSWORD);
  597.                     String alias = null;
  598.                     if(props.containsKey(SecurityConstants.ENCRYPTION_USER)) {
  599.                         alias = (String) props.get(SecurityConstants.ENCRYPTION_USER);
  600.                     }
  601.                     else {
  602.                         alias = aliasGenerico;
  603.                     }
  604.                     if(alias!=null){
  605.                         mapAliasToPassword.put(alias, password);
  606.                     }
  607.                 }

  608.                 if(props.containsKey(SecurityConstants.DECRYPTION_PASSWORD) ||
  609.                         !isPasswordRequired(props, SecurityConstants.DECRYPTION_PROPERTY_REF_ID) ) {
  610.                     String password = (String) props.get(SecurityConstants.DECRYPTION_PASSWORD);
  611.                     String alias = null;
  612.                     if(props.containsKey(SecurityConstants.DECRYPTION_USER)) {
  613.                         alias = (String) props.get(SecurityConstants.DECRYPTION_USER);
  614.                     }
  615.                     else {
  616.                         alias = aliasGenerico;
  617.                     }
  618.                     if(alias!=null){
  619.                         mapAliasToPassword.put(alias, password);
  620.                     }
  621.                 }
  622.                
  623.                 if(props.containsKey(SecurityConstants.USERNAME_TOKEN_PW)) {
  624.                     String password = (String) props.get(SecurityConstants.USERNAME_TOKEN_PW);
  625.                     String alias = aliasGenerico;
  626.                     if(alias!=null){
  627.                         mapAliasToPassword.put(alias, password);
  628.                     }
  629.                 }
  630.                
  631.                 if(props.containsKey(SecurityConstants.USERNAME_TOKEN_PW_MAP)) {
  632.                     String mapUserPassword = (String) props.get(SecurityConstants.USERNAME_TOKEN_PW_MAP);
  633.                     if(mapUserPassword!=null && !"".equals(mapUserPassword)) {
  634.                         Properties convertTextToProperties = PropertiesUtilities.convertTextToProperties(mapUserPassword);
  635.                         if(convertTextToProperties!=null && !convertTextToProperties.isEmpty()) {
  636.                             for (Map.Entry<Object,Object> entry : convertTextToProperties.entrySet()) {
  637.                                 if((entry.getKey() instanceof String) && (entry.getValue() instanceof String)) {
  638.                                     String key = (String) entry.getKey();
  639.                                     String value = (String) entry.getValue();
  640.                                     mapAliasToPassword.put(key, value);
  641.                                 }
  642.                             }
  643.                         }
  644.                     }
  645.                 }
  646.                
  647.                 if(mapAliasToPassword.size()>0) {
  648.                     CallbackHandler pwCallbackHandler = newCallbackHandler(mapAliasToPassword);
  649.                     props.put(SecurityConstants.PASSWORD_CALLBACK_REF, pwCallbackHandler);
  650.                 }
  651.            
  652.             }
  653.         }catch(Exception e){
  654.             throw new SecurityException(e.getMessage(),e);
  655.         }
  656.     }
  657.    
  658.     private static boolean isPasswordRequired(Map<String, Object> props, String refId) {
  659.         Object o = props.get(refId);
  660.         Properties p = null;
  661.         if(o instanceof Properties) {
  662.             p = (Properties) o;
  663.         }
  664.         return isPasswordRequired(p, true);
  665.     }
  666.     public static boolean isPasswordRequired(Properties pr, boolean key) {
  667.         String keystoreType = null;
  668.         keystoreType = pr!=null ? pr.getProperty(KeystoreConstants.PROPERTY_KEYSTORE_TYPE) : null;
  669.         if(keystoreType!=null){
  670.             keystoreType = keystoreType.trim();
  671.         }else{
  672.             keystoreType = KeyStore.getDefaultType();
  673.         }
  674.         boolean required = true;
  675.         if(KeystoreType.JKS.isType(keystoreType)) {
  676.             required = key ? DBUtils.isKeystoreJksKeyPasswordRequired() : DBUtils.isKeystoreJksPasswordRequired();
  677.         }
  678.         else if(KeystoreType.PKCS12.isType(keystoreType)) {
  679.             required = key ? DBUtils.isKeystorePkcs12KeyPasswordRequired() : DBUtils.isKeystorePkcs12PasswordRequired();
  680.         }
  681.         return required;
  682.     }
  683.    
  684.     public static CallbackHandler newCallbackHandler(Map<String, String> mapAliasToPassword) {
  685.         return new CallbackHandler() {
  686.            
  687.             private Map<String, String> mapAliasToPasswordParam = mapAliasToPassword;
  688.            
  689.             @Override
  690.             public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
  691.                  for (int i = 0; i < callbacks.length; i++) {
  692.                      if (callbacks[i] instanceof WSPasswordCallback) {
  693.                             WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
  694.                             if(this.mapAliasToPasswordParam.containsKey(pc.getIdentifier())) {
  695.                                 pc.setPassword(this.mapAliasToPasswordParam.get(pc.getIdentifier()));
  696.                             }
  697.                         } else {
  698.                             throw new UnsupportedCallbackException(callbacks[i],
  699.                                     "Unrecognized Callback");
  700.                         }
  701.                     }
  702.             }
  703.            
  704.         };
  705.     }
  706.    
  707.     /** Utility per verificare l'esistenza di un header di sicurezza */
  708.     public boolean existsSecurityHeader(OpenSPCoop2Message msg,String actor){
  709.         SOAPHeader header = null;
  710.         try{
  711.             if(msg==null){
  712.                 return false;
  713.             }
  714.             if(ServiceBinding.SOAP.equals(msg.getServiceBinding())){
  715.                 OpenSPCoop2SoapMessage soapMsg = msg.castAsSoap();
  716.                 header = soapMsg.getSOAPHeader();
  717.             }
  718.             else{
  719.                 return true;
  720.             }
  721.         }catch(Exception e){
  722.             if(this.log!=null)
  723.                 this.log.error("existsHeaderMessageSecurity error con actor["+actor+"]",e);
  724.             return false;
  725.         }
  726.         return existsSecurityHeader(msg.getFactory(), msg.getMessageType(),
  727.                 header, actor);
  728.     }
  729.     public boolean existsSecurityHeader(OpenSPCoop2Message msg,String actor,
  730.             boolean bufferMessage_readOnly, String idTransazione){
  731.         SOAPEnvelope soapEnvelope = null;
  732.         try{
  733.             if(msg==null){
  734.                 return false;
  735.             }
  736.             if(ServiceBinding.SOAP.equals(msg.getServiceBinding())){
  737.                 OpenSPCoop2SoapMessage soapMsg = msg.castAsSoap();
  738.                 SOAPPart soapPart = MessageUtils.getSOAPPart(soapMsg, bufferMessage_readOnly, idTransazione);
  739.                 if(soapPart!=null) {
  740.                     soapEnvelope = soapPart.getEnvelope();
  741.                 }
  742.             }
  743.             else{
  744.                 return true;
  745.             }
  746.         }catch(Exception e){
  747.             if(this.log!=null)
  748.                 this.log.error("existsHeaderMessageSecurity error con actor["+actor+"]",e);
  749.             return false;
  750.         }
  751.         return existsSecurityHeader(msg.getFactory(), msg.getMessageType(),
  752.                 soapEnvelope, actor);
  753.     }
  754.     public boolean existsSecurityHeader(OpenSPCoop2MessageFactory messageFactory, MessageType messageType,
  755.             SOAPEnvelope soapEnvelope,String actor){
  756.         SOAPHeader header = null;
  757.         try{
  758.             header = soapEnvelope.getHeader();
  759.         }catch(Exception e){
  760.             if(this.log!=null)
  761.                 this.log.error("existsHeaderMessageSecurity error con actor["+actor+"]",e);
  762.             return false;
  763.         }
  764.         return existsSecurityHeader(messageFactory, messageType,
  765.                 header, actor);
  766.     }
  767.     public boolean existsSecurityHeader(OpenSPCoop2MessageFactory messageFactory, MessageType messageType,
  768.             SOAPHeader header,String actor){
  769.         try{
  770.             if(header==null || (SoapUtils.getNotEmptyChildNodes(messageFactory, header).isEmpty()) ){
  771.                 return false;
  772.             }
  773.             java.util.Iterator<?> it = header.examineAllHeaderElements();
  774.             while( it.hasNext()  ){
  775.                
  776.                 // Test Header Element
  777.                 SOAPHeaderElement headerElement = (SOAPHeaderElement) it.next();
  778.                 if(   SecurityConstants.WSS_HEADER_ELEMENT.equals(headerElement.getLocalName()) &&
  779.                         SecurityConstants.WSS_HEADER_ELEMENT_NAMESPACE.equals(headerElement.getNamespaceURI()) ){
  780.                         // potenziale header, verifico l'actor
  781.                     String actorCheck = SoapUtils.getSoapActor(headerElement, messageType);
  782.                     if(actor==null){
  783.                         if(actorCheck==null) {
  784.                             return true;
  785.                         }
  786.                     }else{
  787.                         if(actor.equals(actorCheck)) {
  788.                             return true;
  789.                         }
  790.                     }
  791.                 }
  792.                
  793.             }
  794.             return false;
  795.         }catch(Exception e){
  796.             if(this.log!=null)
  797.                 this.log.error("existsHeaderMessageSecurity error con actor["+actor+"]",e);
  798.             return false;
  799.         }
  800.     }
  801.    
  802.    

  803.     public SOAPHeaderElement getSecurityHeader(OpenSPCoop2Message msg,String actor){
  804.         SOAPHeader header = null;
  805.         try{
  806.             if(msg==null){
  807.                 return null;
  808.             }
  809.             if(ServiceBinding.SOAP.equals(msg.getServiceBinding())){
  810.                 OpenSPCoop2SoapMessage soapMsg = msg.castAsSoap();
  811.                 header = soapMsg.getSOAPHeader();
  812.             }
  813.             else{
  814.                 return null;
  815.             }
  816.         }catch(Exception e){
  817.             if(this.log!=null)
  818.                 this.log.error("getHeaderMessageSecurity error con actor["+actor+"]",e);
  819.             return null;
  820.         }
  821.         return getSecurityHeader(msg.getFactory(), msg.getMessageType(),
  822.                 header, actor);
  823.     }
  824.     public SOAPHeaderElement getSecurityHeader(OpenSPCoop2Message msg,String actor,
  825.             boolean bufferMessageReadOnly, String idTransazione){
  826.         SOAPEnvelope soapEnvelope = null;
  827.         try{
  828.             if(msg==null){
  829.                 return null;
  830.             }
  831.             if(ServiceBinding.SOAP.equals(msg.getServiceBinding())){
  832.                 OpenSPCoop2SoapMessage soapMsg = msg.castAsSoap();
  833.                 SOAPPart soapPart = MessageUtils.getSOAPPart(soapMsg, bufferMessageReadOnly, idTransazione);
  834.                 if(soapPart!=null) {
  835.                     soapEnvelope = soapPart.getEnvelope();
  836.                 }
  837.             }
  838.             else{
  839.                 return null;
  840.             }
  841.         }catch(Exception e){
  842.             if(this.log!=null)
  843.                 this.log.error("getHeaderMessageSecurity error con actor["+actor+"]",e);
  844.             return null;
  845.         }
  846.         return getSecurityHeader(msg.getFactory(), msg.getMessageType(),
  847.                 soapEnvelope, actor);
  848.     }
  849.     public SOAPHeaderElement getSecurityHeader(OpenSPCoop2MessageFactory messageFactory, MessageType messageType,
  850.             SOAPEnvelope soapEnvelope,String actor){
  851.         SOAPHeader header = null;
  852.         try{
  853.             header = soapEnvelope.getHeader();
  854.         }catch(Exception e){
  855.             if(this.log!=null)
  856.                 this.log.error("getHeaderMessageSecurity error con actor["+actor+"]",e);
  857.             return null;
  858.         }
  859.         return getSecurityHeader(messageFactory, messageType,
  860.                 header, actor);
  861.     }
  862.     public SOAPHeaderElement getSecurityHeader(OpenSPCoop2MessageFactory messageFactory, MessageType messageType,
  863.             SOAPHeader header,String actor){
  864.         try{
  865.             if(header==null || (SoapUtils.getNotEmptyChildNodes(messageFactory, header).isEmpty()) ){
  866.                 return null;
  867.             }
  868.             java.util.Iterator<?> it = header.examineAllHeaderElements();
  869.             while( it.hasNext()  ){
  870.                
  871.                 // Test Header Element
  872.                 SOAPHeaderElement headerElement = (SOAPHeaderElement) it.next();
  873.                 if(   SecurityConstants.WSS_HEADER_ELEMENT.equals(headerElement.getLocalName()) &&
  874.                         SecurityConstants.WSS_HEADER_ELEMENT_NAMESPACE.equals(headerElement.getNamespaceURI()) ){
  875.                         // potenziale header, verifico l'actor
  876.                     String actorCheck = SoapUtils.getSoapActor(headerElement, messageType);
  877.                     if(actor==null){
  878.                         if(actorCheck==null) {
  879.                             return headerElement;
  880.                         }
  881.                     }else{
  882.                         if(actor.equals(actorCheck)) {
  883.                             return headerElement;
  884.                         }
  885.                     }
  886.                 }
  887.                
  888.             }
  889.             return null;
  890.         }catch(Exception e){
  891.             if(this.log!=null)
  892.                 this.log.error("getHeaderMessageSecurity error con actor["+actor+"]",e);
  893.             return null;
  894.         }
  895.     }

  896.    
  897.     /** Utility per verificare l'esistenza di un header di sicurezza */
  898.     public SOAPElement getSAMLTokenInSecurityHeader(OpenSPCoop2MessageFactory messageFactory, SOAPHeaderElement securityHeader,String samlVersion){
  899.         try{
  900.             SOAPElement samlElement = null;
  901.                        
  902.             DynamicNamespaceContext dnc = new DynamicNamespaceContext();
  903.             dnc.findPrefixNamespace(securityHeader);
  904.                        
  905.             AbstractXPathExpressionEngine xpathExpressionEngine = new XPathExpressionEngine(messageFactory);
  906.             String xpath =null;
  907.             if(SecurityConstants.SAML_VERSION_XMLCONFIG_ID_VALUE_20.equals(samlVersion)) {
  908.                 xpath = SAMLConstants.XPATH_SAML_20_ASSERTION;
  909.             }
  910.             else {
  911.                 xpath = SAMLConstants.XPATH_SAML_11_ASSERTION;
  912.             }
  913.             try {
  914.                 Object o = xpathExpressionEngine.getMatchPattern(securityHeader, dnc, xpath, XPathReturnType.NODE);
  915.                 samlElement = (SOAPElement) o;
  916.             } catch(XPathNotFoundException e) {
  917.                 // ignore
  918.             }
  919.            
  920.             return samlElement;

  921.         }catch(Exception e){
  922.             if(this.log!=null)
  923.                 this.log.error("getSAMLTokenInSecurityHeader error, saml version: ["+samlVersion+"]",e);
  924.             return null;
  925.         }
  926.     }

  927.     public String getSAMLTokenSubjectConfirmationMethodInSecurityHeader(OpenSPCoop2MessageFactory messageFactory, SOAPElement samlToken,String samlVersion){
  928.         try{
  929.                
  930.             DynamicNamespaceContext dnc = new DynamicNamespaceContext();
  931.             dnc.findPrefixNamespace(samlToken);
  932.                    
  933.             AbstractXPathExpressionEngine xpathExpressionEngine = new XPathExpressionEngine(messageFactory);
  934.             String xpath =null;
  935.             if(SecurityConstants.SAML_VERSION_XMLCONFIG_ID_VALUE_20.equals(samlVersion)) {
  936.                 xpath = SAMLConstants.XPATH_SAML_20_ASSERTION_SUBJECT_CONFIRMATION_METHOD;
  937.             }
  938.             else {
  939.                 xpath = SAMLConstants.XPATH_SAML_11_ASSERTION_SUBJECT_CONFIRMATION_METHOD;
  940.             }
  941.             String method = null;
  942.             try {
  943.                 Object o = xpathExpressionEngine.getMatchPattern(samlToken, dnc, xpath, XPathReturnType.STRING);
  944.                 method = (String) o;
  945.             } catch(XPathNotFoundException e) {
  946.                 // ignore
  947.             }
  948.            
  949.             return method;

  950.         }catch(Exception e){
  951.             if(this.log!=null)
  952.                 this.log.error("getSAMLTokenSubjectConfirmationMethodInSecurityHeader error, saml version: ["+samlVersion+"]",e);
  953.             return null;
  954.         }  
  955. }
  956.    
  957. }