WSSUtils.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.soapbox;

  21. import java.security.cert.X509Certificate;
  22. import java.util.Iterator;

  23. import javax.xml.namespace.QName;
  24. import javax.xml.soap.SOAPException;
  25. import javax.xml.soap.SOAPHeaderElement;

  26. import org.adroitlogic.soapbox.CryptoUtil;
  27. import org.adroitlogic.soapbox.MessageSecurityContext;
  28. import org.adroitlogic.soapbox.SBConstants;
  29. import org.adroitlogic.soapbox.SecurityConfig;
  30. import org.adroitlogic.soapbox.SecurityRequest;
  31. import org.apache.wss4j.common.token.DOMX509Data;
  32. import org.apache.wss4j.common.token.DOMX509IssuerSerial;
  33. import org.openspcoop2.message.OpenSPCoop2SoapMessage;
  34. import org.openspcoop2.message.exception.MessageException;
  35. import org.openspcoop2.message.exception.MessageNotSupportedException;
  36. import org.openspcoop2.message.soap.SoapUtils;
  37. import org.openspcoop2.security.SecurityException;
  38. import org.w3c.dom.Document;
  39. import org.w3c.dom.Element;
  40. import org.w3c.dom.NamedNodeMap;
  41. import org.w3c.dom.Node;
  42. import org.w3c.dom.NodeList;

  43. /**
  44.  * WSSContext_soapbox
  45.  *
  46.  * @author Andrea Poli (apoli@link.it)
  47.  * @author $Author$
  48.  * @version $Rev$, $Date$
  49.  */
  50. public class WSSUtils {

  51.     public static void initWSSecurityHeader(OpenSPCoop2SoapMessage message,String actor,boolean mustUnderstand) throws SOAPException, MessageException, MessageNotSupportedException {

  52.         if(message.getSOAPHeader()==null){
  53.             message.getSOAPPart().getEnvelope().addHeader();
  54.         }

  55.         Iterator<?> it = message.getSOAPHeader().getChildElements(new QName(SBConstants.WSSE, "Security"));
  56.         if(it.hasNext()){
  57.             return;
  58.         }

  59.         QName name = new QName(SBConstants.WSSE, "Security");
  60.         SOAPHeaderElement headerwss = message.newSOAPHeaderElement(message.getSOAPHeader(), name);
  61.         headerwss.setActor(actor);
  62.         headerwss.setMustUnderstand(mustUnderstand);
  63.         headerwss.setParentElement(message.getSOAPHeader());
  64.         message.addHeaderElement(message.getSOAPHeader(), headerwss);
  65.        
  66.         return;
  67.     }

  68.     public static SOAPHeaderElement getWSSecurityHeader(OpenSPCoop2SoapMessage message,String actor,boolean mustUnderstand) throws SOAPException, MessageException, MessageNotSupportedException {

  69.         if(message.getSOAPHeader()==null){
  70.             message.getSOAPPart().getEnvelope().addHeader();
  71.         }

  72.         Iterator<?> it = message.getSOAPHeader().getChildElements(new QName(SBConstants.WSSE, "Security"));
  73.         while(it.hasNext()){
  74.             SOAPHeaderElement hdr = (SOAPHeaderElement) it.next();
  75.             String actorCheck = SoapUtils.getSoapActor(hdr, message.getMessageType());
  76.             boolean mustUnderstandFound = hdr.getMustUnderstand();
  77.             if(mustUnderstand!=mustUnderstandFound)
  78.                 continue;
  79.             if(actor==null){
  80.                 if(actorCheck!=null){
  81.                     continue;
  82.                 }
  83.             }else{
  84.                 if(!actor.equals(actorCheck)){
  85.                     continue;
  86.                 }
  87.             }
  88.             return hdr;
  89.         }


  90.         throw new SOAPException("NotFound");

  91.     }

  92.     public static Element getWSSecurityHeader(Document doc,String actor,boolean mustUnderstand) throws SecurityException {

  93.         String ns = SBConstants.WSSE;
  94.         String localName = "Security";

  95.         NodeList nl = doc.getDocumentElement().getElementsByTagNameNS(ns, localName);
  96.         if(nl==null || nl.getLength()<=0){
  97.             throw new SecurityException("Header WSS not found");
  98.         }
  99.         for (int i = 0; i < nl.getLength(); i++) {

  100.             Node n = nl.item(i);
  101.             if((n instanceof Element) && localName.equals(n.getLocalName()) && ns.equals(n.getNamespaceURI())){

  102.                 String actorFound = null;
  103.                 boolean mustUnderstandFound = false;

  104.                 NamedNodeMap attributes = n.getAttributes();
  105.                 for (int j = 0; j < attributes.getLength(); j++) {

  106.                     Node a = attributes.item(j);
  107.                     String localNameAttribute = a.getLocalName();
  108.                     //String prefixAttribute = a.getPrefix();
  109.                     String namespaceAttribute = a.getNamespaceURI();
  110.                     String valueAttribute = a.getNodeValue();
  111.                     //System.out.println("LOCAL["+localNameAttribute+"] PREFIX["+prefixAttribute+"] NAMESPACe["+namespaceAttribute+"] VALUE["+valueAttribute+"]");

  112.                     if("actor".equals(localNameAttribute) && "http://schemas.xmlsoap.org/soap/envelope/".equals(namespaceAttribute)){
  113.                         actorFound =  valueAttribute;
  114.                     }
  115.                     else if("mustUnderstand".equals(localNameAttribute) && "http://schemas.xmlsoap.org/soap/envelope/".equals(namespaceAttribute)){
  116.                         mustUnderstandFound = "1".equals(valueAttribute);
  117.                     }

  118.                 }

  119.                 if(mustUnderstand!=mustUnderstandFound)
  120.                     continue;
  121.                 if(actor==null){
  122.                     if(actorFound!=null){
  123.                         continue;
  124.                     }
  125.                 }else{
  126.                     if(!actor.equals(actorFound)){
  127.                         continue;
  128.                     }
  129.                 }

  130.                 return (Element) n;

  131.             }

  132.         }
  133.         throw new SecurityException("Header WSS not found");
  134.     }

  135.     @SuppressWarnings("incomplete-switch")
  136.     public static Element createKeyInfoElement(
  137.             Document doc, SecurityRequest secReq, MessageSecurityContext msgSecCtx, SecurityConfig secConfig) {

  138.         Element keyInfoElem = CryptoUtil.createKeyInfoElement(doc, secReq, msgSecCtx, secConfig);

  139.         // Gestisco casi non coperti da createKeyInfoElement

  140.         switch (secReq.getKeyIdentifierType()) {
  141.         case ISSUER_SERIAL :
  142.             String alias = secReq.getCertAlias();
  143.             X509Certificate[] certs = secConfig.getCertificatesByAlias(alias);
  144.             String issuer = certs[0].getIssuerX500Principal().getName();
  145.             java.math.BigInteger serialNumber = certs[0].getSerialNumber();
  146.             DOMX509IssuerSerial domIssuerSerial =
  147.                     new DOMX509IssuerSerial(doc, issuer, serialNumber);
  148.             DOMX509Data domX509Data = new DOMX509Data(doc, domIssuerSerial);
  149.             keyInfoElem.getElementsByTagNameNS(SBConstants.WSSE, "SecurityTokenReference").item(0).appendChild(domX509Data.getElement());
  150.             break;
  151.         }

  152.         return keyInfoElem;
  153.        
  154.     }

  155. }