WSSUtils.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2024 Link.it srl (https://link.it).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openspcoop2.security.message.soapbox;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeaderElement;
import org.adroitlogic.soapbox.CryptoUtil;
import org.adroitlogic.soapbox.MessageSecurityContext;
import org.adroitlogic.soapbox.SBConstants;
import org.adroitlogic.soapbox.SecurityConfig;
import org.adroitlogic.soapbox.SecurityRequest;
import org.apache.wss4j.common.token.DOMX509Data;
import org.apache.wss4j.common.token.DOMX509IssuerSerial;
import org.openspcoop2.message.OpenSPCoop2SoapMessage;
import org.openspcoop2.message.exception.MessageException;
import org.openspcoop2.message.exception.MessageNotSupportedException;
import org.openspcoop2.message.soap.SoapUtils;
import org.openspcoop2.security.SecurityException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* WSSContext_soapbox
*
* @author Andrea Poli (apoli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public class WSSUtils {
public static void initWSSecurityHeader(OpenSPCoop2SoapMessage message,String actor,boolean mustUnderstand) throws SOAPException, MessageException, MessageNotSupportedException {
if(message.getSOAPHeader()==null){
message.getSOAPPart().getEnvelope().addHeader();
}
Iterator<?> it = message.getSOAPHeader().getChildElements(new QName(SBConstants.WSSE, "Security"));
if(it.hasNext()){
return;
}
QName name = new QName(SBConstants.WSSE, "Security");
SOAPHeaderElement headerwss = message.newSOAPHeaderElement(message.getSOAPHeader(), name);
headerwss.setActor(actor);
headerwss.setMustUnderstand(mustUnderstand);
headerwss.setParentElement(message.getSOAPHeader());
message.addHeaderElement(message.getSOAPHeader(), headerwss);
return;
}
public static SOAPHeaderElement getWSSecurityHeader(OpenSPCoop2SoapMessage message,String actor,boolean mustUnderstand) throws SOAPException, MessageException, MessageNotSupportedException {
if(message.getSOAPHeader()==null){
message.getSOAPPart().getEnvelope().addHeader();
}
Iterator<?> it = message.getSOAPHeader().getChildElements(new QName(SBConstants.WSSE, "Security"));
while(it.hasNext()){
SOAPHeaderElement hdr = (SOAPHeaderElement) it.next();
String actorCheck = SoapUtils.getSoapActor(hdr, message.getMessageType());
boolean mustUnderstandFound = hdr.getMustUnderstand();
if(mustUnderstand!=mustUnderstandFound)
continue;
if(actor==null){
if(actorCheck!=null){
continue;
}
}else{
if(!actor.equals(actorCheck)){
continue;
}
}
return hdr;
}
throw new SOAPException("NotFound");
}
public static Element getWSSecurityHeader(Document doc,String actor,boolean mustUnderstand) throws SecurityException {
String ns = SBConstants.WSSE;
String localName = "Security";
NodeList nl = doc.getDocumentElement().getElementsByTagNameNS(ns, localName);
if(nl==null || nl.getLength()<=0){
throw new SecurityException("Header WSS not found");
}
for (int i = 0; i < nl.getLength(); i++) {
Node n = nl.item(i);
if((n instanceof Element) && localName.equals(n.getLocalName()) && ns.equals(n.getNamespaceURI())){
String actorFound = null;
boolean mustUnderstandFound = false;
NamedNodeMap attributes = n.getAttributes();
for (int j = 0; j < attributes.getLength(); j++) {
Node a = attributes.item(j);
String localNameAttribute = a.getLocalName();
//String prefixAttribute = a.getPrefix();
String namespaceAttribute = a.getNamespaceURI();
String valueAttribute = a.getNodeValue();
//System.out.println("LOCAL["+localNameAttribute+"] PREFIX["+prefixAttribute+"] NAMESPACe["+namespaceAttribute+"] VALUE["+valueAttribute+"]");
if("actor".equals(localNameAttribute) && "http://schemas.xmlsoap.org/soap/envelope/".equals(namespaceAttribute)){
actorFound = valueAttribute;
}
else if("mustUnderstand".equals(localNameAttribute) && "http://schemas.xmlsoap.org/soap/envelope/".equals(namespaceAttribute)){
mustUnderstandFound = "1".equals(valueAttribute);
}
}
if(mustUnderstand!=mustUnderstandFound)
continue;
if(actor==null){
if(actorFound!=null){
continue;
}
}else{
if(!actor.equals(actorFound)){
continue;
}
}
return (Element) n;
}
}
throw new SecurityException("Header WSS not found");
}
@SuppressWarnings("incomplete-switch")
public static Element createKeyInfoElement(
Document doc, SecurityRequest secReq, MessageSecurityContext msgSecCtx, SecurityConfig secConfig) {
Element keyInfoElem = CryptoUtil.createKeyInfoElement(doc, secReq, msgSecCtx, secConfig);
// Gestisco casi non coperti da createKeyInfoElement
switch (secReq.getKeyIdentifierType()) {
case ISSUER_SERIAL :
String alias = secReq.getCertAlias();
X509Certificate[] certs = secConfig.getCertificatesByAlias(alias);
String issuer = certs[0].getIssuerX500Principal().getName();
java.math.BigInteger serialNumber = certs[0].getSerialNumber();
DOMX509IssuerSerial domIssuerSerial =
new DOMX509IssuerSerial(doc, issuer, serialNumber);
DOMX509Data domX509Data = new DOMX509Data(doc, domIssuerSerial);
keyInfoElem.getElementsByTagNameNS(SBConstants.WSSE, "SecurityTokenReference").item(0).appendChild(domX509Data.getElement());
break;
}
return keyInfoElem;
}
}