MessageSecurityReceiver_soapbox.java
- /*
- * GovWay - A customizable API Gateway
- * https://govway.org
- *
- * Copyright (c) 2005-2025 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.io.ByteArrayOutputStream;
- import java.io.PrintStream;
- import java.security.PublicKey;
- import java.security.cert.X509Certificate;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import javax.xml.namespace.QName;
- import javax.xml.soap.AttachmentPart;
- import javax.xml.soap.SOAPException;
- import javax.xml.soap.SOAPPart;
- import org.adroitlogic.soapbox.MessageSecurityContext;
- import org.adroitlogic.ultraesb.core.MessageImpl;
- import org.openspcoop2.message.OpenSPCoop2Message;
- import org.openspcoop2.message.OpenSPCoop2SoapMessage;
- import org.openspcoop2.message.constants.ServiceBinding;
- import org.openspcoop2.message.exception.MessageException;
- import org.openspcoop2.message.exception.MessageNotSupportedException;
- import org.openspcoop2.message.soap.reference.Reference;
- import org.openspcoop2.protocol.sdk.Busta;
- import org.openspcoop2.protocol.sdk.constants.CodiceErroreCooperazione;
- import org.openspcoop2.security.SecurityException;
- import org.openspcoop2.security.message.AbstractSOAPMessageSecurityReceiver;
- import org.openspcoop2.security.message.SubErrorCodeSecurity;
- import org.openspcoop2.security.message.constants.SecurityConstants;
- import org.openspcoop2.security.message.engine.MessageUtilities;
- import org.openspcoop2.security.message.engine.WSSUtilities;
- import org.openspcoop2.security.message.utils.EncryptionBean;
- import org.openspcoop2.security.message.utils.KeystoreUtils;
- import org.openspcoop2.security.message.utils.SignatureBean;
- import org.openspcoop2.utils.Utilities;
- import org.openspcoop2.utils.certificate.KeyStore;
- import org.openspcoop2.utils.resources.ClassLoaderUtilities;
- import org.w3c.dom.Document;
- /**
- * WSSContext_soapbox
- *
- * @author Andrea Poli (apoli@link.it)
- * @author Giovanni Bussu (bussu@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class MessageSecurityReceiver_soapbox extends AbstractSOAPMessageSecurityReceiver{
- private X509Certificate [] certificates = null;
-
- @Override
- public void process(org.openspcoop2.security.message.MessageSecurityContext messageSecurityContext,OpenSPCoop2Message messageParam,Busta busta,org.openspcoop2.utils.Map<Object> ctx) throws SecurityException{
- try{
-
- if(ServiceBinding.SOAP.equals(messageParam.getServiceBinding())==false){
- throw new SecurityException("SoapBox Engine usable only with SOAP Binding");
- }
- OpenSPCoop2SoapMessage message = messageParam.castAsSoap();
-
-
-
- // ********** Leggo operazioni ***************
- boolean decrypt = false;
- boolean signature = false;
- boolean timestamp = false;
- String[]actions = ((String)messageSecurityContext.getIncomingProperties().get(SecurityConstants.ACTION)).split(" ");
- for (int i = 0; i < actions.length; i++) {
- if(SecurityConstants.isActionEncryption(actions[i].trim())){
- decrypt = true;
- }
- else if(SecurityConstants.SIGNATURE_ACTION.equals(actions[i].trim())){
- signature = true;
- }
- else if(SecurityConstants.TIMESTAMP_ACTION.equals(actions[i].trim())){
- timestamp = true;
- }
- }
- // rilasciato vincolo di abilitazione signature o encryption per abilitare il timestamp
- // if(!signature && !decrypt && timestamp){
- // throw new WSSException("La funzionalita' "+WSSConstants.TIMESTAMP_ACTION+" richiede per essere abilitata almeno una delle seguenti altre funzionalita': "+
- // WSSConstants.ENCRYPT_ACTION+","+WSSConstants.SIGNATURE_ACTION);
- // }
-
-
-
-
- // ********** Inizializzo Header WSS ***************
- SOAPPart sp = message.getSOAPPart();
- //Document d = sp;
- Document d = sp.getDocumentElement().getOwnerDocument();
- Object mustUnderstandObject = messageSecurityContext.getIncomingProperties().get(SecurityConstants.MUST_UNDERSTAND);
- boolean mustUnderstand = false;
- if(mustUnderstandObject!=null){
- mustUnderstand = SecurityConstants.TRUE.equals(mustUnderstandObject);
- }
- MessageSecurityContext msgSecCtx = new MessageSecurityContext(d, new MessageImpl(true, null, "http"));
- Iterator<?> it = message.getAttachments();
- if(it!=null){
- while(it.hasNext()) {
- AttachmentPart part = (AttachmentPart) it.next();
- String contentId = part.getContentId();
- if(contentId.startsWith("<"))
- contentId = contentId.substring(1);
- if(contentId.endsWith(">"))
- contentId = contentId.substring(0,contentId.length()-1);
- msgSecCtx.setProperty(contentId, part); //tolgo < e > dal nome eventualmente
- }
- }
-
-
-
-
-
-
- // **************** Inizializzo process per validare timestamp **************************
-
- ProcessTimestampedMessage verifyTimestampedProc = null;
- if(timestamp){
- verifyTimestampedProc = new ProcessTimestampedMessage();
-
- //future time to live
- Object futureTtlObject = messageSecurityContext.getIncomingProperties().get(SecurityConstants.TIMESTAMP_FUTURE_TTL);
- if(futureTtlObject==null){
- futureTtlObject = SecurityConstants.TIMESTAMP_SOAPBOX_FUTURE_TTL_DEFAULT;
- }
- String ttl = (String) futureTtlObject;
- long futureTtlLong = -1;
- try{
- futureTtlLong = Long.parseLong(ttl);
- }catch(Exception e){
- throw new Exception("Indicazione "+SecurityConstants.TIMESTAMP_FUTURE_TTL+" non corretta: "+e.getMessage());
- }
- msgSecCtx.setProperty(SecurityConstants.TIMESTAMP_FUTURE_TTL, futureTtlLong * 1000l);
- //strict Timestamp handling
- Object strictObject = messageSecurityContext.getIncomingProperties().get(SecurityConstants.TIMESTAMP_STRICT);
- if(strictObject==null){
- strictObject = SecurityConstants.TRUE;
- }
- String strict = (String) strictObject;
- boolean strictBoolean = false;
- try{
- strictBoolean = Boolean.parseBoolean(strict);
- }catch(Exception e){
- throw new Exception("Indicazione "+SecurityConstants.TIMESTAMP_STRICT+" non corretta: "+e.getMessage());
- }
- msgSecCtx.setProperty(SecurityConstants.TIMESTAMP_STRICT, strictBoolean);
- }
-
-
-
-
-
-
- // **************** Inizializzo process per decifrare **************************
- ProcessPartialEncryptedMessage decryptMsgProc = null;
- if(decrypt){
- decryptMsgProc = (ProcessPartialEncryptedMessage) ClassLoaderUtilities.newInstance(message.getProcessPartialEncryptedMessageClass());
- decryptMsgProc.setMessage(message);
- decryptMsgProc.setActor(messageSecurityContext.getActor());
- decryptMsgProc.setMustUnderstand(mustUnderstand);
- }
-
-
-
-
-
-
-
- // **************** Inizializzo process per validare la firma **************************
-
- ProcessSignedMessage signMsgProc = null;
- if(signature){
- signMsgProc = new ProcessSignedMessage();
- signMsgProc.setMessage(message);
- signMsgProc.setActor(messageSecurityContext.getActor());
- signMsgProc.setMustUnderstand(mustUnderstand);
- }
-
-
-
-
-
-
-
-
-
- // **************** Leggo parametri decryption store **************************
- KeyStore decryptionKS = null;
- KeyStore decryptionTrustStoreKS = null;
- String aliasDecryptUser = null;
- String aliasDecryptPassword = null;
- boolean decryptionSymmetric = false;
- if(decrypt){
- EncryptionBean bean = KeystoreUtils.getReceiverEncryptionBean(messageSecurityContext,ctx);
-
- decryptionKS = bean.getKeystore();
- decryptionTrustStoreKS = bean.getTruststore();
- decryptionSymmetric = bean.isEncryptionSimmetric();
- aliasDecryptUser = bean.getUser();
- aliasDecryptPassword = bean.getPassword();
-
- }
-
-
-
-
- // **************** Leggo parametri signature store **************************
- KeyStore signatureKS = null;
- KeyStore signatureTrustStoreKS = null;
- String aliasSignatureUser = null;
- String aliasSignaturePassword = null;
- String crlPath = null;
- if(signature){
-
- SignatureBean bean = KeystoreUtils.getReceiverSignatureBean(messageSecurityContext,ctx);
-
- signatureKS = bean.getKeystore();
- signatureTrustStoreKS = bean.getTruststore();
- aliasSignatureUser = bean.getUser();
- aliasSignaturePassword = bean.getPassword();
- crlPath = bean.getCrlPath();
- }
-
-
-
-
-
-
-
-
-
-
- // **************** Inizializzo Secure Context for encryption **************************
- org.openspcoop2.security.message.soapbox.SoapBoxSecurityConfig securityConfig_decryption = null;
- if(decrypt){
- msgSecCtx.getEncryptionRequest().setCertAlias(aliasDecryptUser);
-
- Map<String, String> passwordMap_decryption = new HashMap<>();
- passwordMap_decryption.put(aliasDecryptUser, aliasDecryptPassword);
- if(decryptionTrustStoreKS==null){
- decryptionTrustStoreKS = decryptionKS;
- }
- securityConfig_decryption = new org.openspcoop2.security.message.soapbox.SoapBoxSecurityConfig(decryptionKS, decryptionTrustStoreKS, passwordMap_decryption,ctx);
- securityConfig_decryption.setSymmetricSharedKey(decryptionSymmetric);
- }
-
-
-
-
-
-
-
-
-
- // **************** Inizializzo Secure Context for signature **************************
- org.openspcoop2.security.message.soapbox.SoapBoxSecurityConfig securityConfig_signature = null;
- if(signature){
- Map<String, String> passwordMap_signature = new HashMap<>();
- passwordMap_signature.put(aliasSignatureUser, aliasSignaturePassword);
- if(signatureTrustStoreKS==null){
- signatureTrustStoreKS = signatureKS;
- }
- securityConfig_signature = new org.openspcoop2.security.message.soapbox.SoapBoxSecurityConfig(signatureKS, signatureTrustStoreKS, passwordMap_signature,crlPath,ctx);
- }
-
-
-
-
-
-
-
-
-
- // **************** Process **************************
- // Devo rileggerle per eseguire nell'ordine
- actions = ((String)messageSecurityContext.getIncomingProperties().get(SecurityConstants.ACTION)).split(" ");
- for (int i = actions.length-1; i >= 0; i--) {
- if(SecurityConstants.isActionEncryption(actions[i].trim()) || SecurityConstants.isActionDecryption(actions[i].trim())){
- decryptMsgProc.process(securityConfig_decryption, msgSecCtx);
- //refreshAttachments(message); // per impostare il nuovo contenuto degli attachment, una volta decriptati (non serve se non si imposta il CONTENT_TRANSFER_ENCODING a base64!!)
- }
- else if(SecurityConstants.SIGNATURE_ACTION.equals(actions[i].trim())){
- signMsgProc.process(securityConfig_signature, msgSecCtx);
- this.certificates = signMsgProc.getCertificates();
- }
- else if(SecurityConstants.TIMESTAMP_ACTION.equals(actions[i].trim())){
- if(securityConfig_signature!=null){
- verifyTimestampedProc.process(securityConfig_signature, msgSecCtx);
- }
- else if(securityConfig_decryption!=null){
- verifyTimestampedProc.process(securityConfig_decryption, msgSecCtx);
- } else {
- verifyTimestampedProc.process(null, msgSecCtx);
- }
- }
- }
-
-
-
-
-
-
-
-
-
- } catch (Exception e) {
-
- SecurityException wssException = new SecurityException(e.getMessage(), e);
-
-
- /* **** MESSAGGIO ***** */
- String msg = Utilities.getInnerNotEmptyMessageException(e).getMessage();
-
- Throwable innerExc = Utilities.getLastInnerException(e);
- String innerMsg = null;
- if(innerExc!=null){
- innerMsg = innerExc.getMessage();
- }
-
- String messaggio = null;
- if(msg!=null){
- messaggio = new String(msg);
- if(innerMsg!=null && !innerMsg.equals(msg)){
- messaggio = messaggio + " ; " + innerMsg;
- }
- }
- else{
- if(innerMsg!=null){
- messaggio = innerMsg;
- }
- }
-
- wssException.setMsgErrore(messaggio);
-
-
- /* ***** CODICE **** */
-
- boolean signature = false;
- boolean encrypt = false;
- try{
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- PrintStream printStream = new PrintStream(bout);
- e.printStackTrace(printStream);
- bout.flush();
- printStream.flush();
- bout.close();
- printStream.close();
-
- if(bout.toString().contains("ProcessSignedMessage")){
- signature = true;
- }
- else if(bout.toString().contains("Signature verification failed")){
- signature = true;
- }
- else if(bout.toString().contains("Message is not signed")){
- signature = true;
- }
- else if(bout.toString().contains("ProcessPartialEncryptedMessage")){
- encrypt = true;
- }
-
- }catch(Exception eClose){}
-
- if(signature){
- wssException.setCodiceErrore(CodiceErroreCooperazione.SICUREZZA_FIRMA_NON_VALIDA);
- }
- else if(encrypt){
- wssException.setCodiceErrore(CodiceErroreCooperazione.SICUREZZA_CIFRATURA_NON_VALIDA);
- }
- else {
- wssException.setCodiceErrore(CodiceErroreCooperazione.SICUREZZA);
- }
-
-
-
- throw wssException;
- }
- }
- @SuppressWarnings("unused")
- private void refreshAttachments(OpenSPCoop2SoapMessage openspcoop2Message) throws MessageException, MessageNotSupportedException, SOAPException{
- java.util.Iterator<?> itAp = openspcoop2Message.getAttachments();
- List<AttachmentPart> v = new ArrayList<AttachmentPart>();
- while(itAp.hasNext()){
- AttachmentPart ap =
- (AttachmentPart) itAp.next();
- v.add(ap);
- }
- openspcoop2Message.removeAllAttachments();
- while(v.size()>0){
- AttachmentPart ap = v.remove(0);
- AttachmentPart apNew = openspcoop2Message.createAttachmentPart();
- apNew.setDataHandler(ap.getDataHandler());
- Iterator<?> itMhs = ap.getAllMimeHeaders();
- while (itMhs.hasNext()) {
- javax.xml.soap.MimeHeader mh = (javax.xml.soap.MimeHeader) itMhs.next();
- //System.out.println("TIPO["+mh.getName()+"] VALUE["+mh.getValue()+"]");
- if(!"Content-Transfer-Encoding".equals(mh.getName())){
- apNew.addMimeHeader(mh.getName(), mh.getValue());
- }
- }
- openspcoop2Message.addAttachmentPart(apNew);
- }
- }
-
-
- @Override
- public String getCertificate() throws SecurityException{
- if(this.certificates!=null &&
- this.certificates.length > 0){
- return this.certificates[0].getSubjectX500Principal().toString();
- }
- return null;
- }
-
- @Override
- public X509Certificate getX509Certificate() throws SecurityException {
- if(this.certificates!=null &&
- this.certificates.length > 0){
- return this.certificates[0];
- }
- return null;
- }
- @Override
- public PublicKey getPublicKey() {
- if(this.certificates!=null &&
- this.certificates.length > 0){
- return this.certificates[0].getPublicKey();
- }
- return null;
- }
-
- @Override
- public String getCertificateId() throws SecurityException{
- return null;
- }
-
- @Override
- public List<Reference> getDirtyElements(
- org.openspcoop2.security.message.MessageSecurityContext messageSecurityContext,
- OpenSPCoop2SoapMessage message) throws SecurityException {
- return WSSUtilities.getDirtyElements(messageSecurityContext, message);
- }
- @Override
- public Map<QName, QName> checkEncryptSignatureParts(
- org.openspcoop2.security.message.MessageSecurityContext messageSecurityContext,
- List<Reference> elementsToClean, OpenSPCoop2SoapMessage message,
- List<SubErrorCodeSecurity> codiciErrore) throws SecurityException {
- return MessageUtilities.checkEncryptSignatureParts(messageSecurityContext, elementsToClean, message, codiciErrore, SecurityConstants.QNAME_WSS_ELEMENT_SECURITY);
- }
- @Override
- public void checkEncryptionPartElements(Map<QName, QName> notResolved,
- OpenSPCoop2SoapMessage message,
- List<SubErrorCodeSecurity> erroriRilevati) throws SecurityException {
- MessageUtilities.checkEncryptionPartElements(notResolved, message, erroriRilevati);
- }
- @Override
- public void cleanDirtyElements(
- org.openspcoop2.security.message.MessageSecurityContext messageSecurityContext,
- OpenSPCoop2SoapMessage message, List<Reference> elementsToClean,
- boolean detachHeaderWSSecurity, boolean removeAllIdRef)
- throws SecurityException {
- WSSUtilities.cleanDirtyElements(messageSecurityContext, message, elementsToClean, detachHeaderWSSecurity,removeAllIdRef);
-
- }
-
- }