SignPartialMessageProcessor.java

  1. /*
  2.  * AdroitLogic UltraESB Enterprise Service Bus
  3.  *
  4.  * Copyright (c) 2010-2012 AdroitLogic Private Ltd. (http://adroitlogic.org). All Rights Reserved.
  5.  *
  6.  * GNU Affero General Public License Usage
  7.  *
  8.  * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
  9.  * Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option)
  10.  * any later version.
  11.  *
  12.  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
  13.  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for
  14.  * more details.
  15.  *
  16.  * You should have received a copy of the GNU Affero General Public License along with this program (See LICENSE-AGPL.TXT).
  17.  * If not, see http://www.gnu.org/licenses/agpl-3.0.html
  18.  *
  19.  * Commercial Usage
  20.  *
  21.  * Licensees holding valid UltraESB Commercial licenses may use this file in accordance with the UltraESB Commercial
  22.  * License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written
  23.  * agreement between you and AdroitLogic.
  24.  *
  25.  * If you are unsure which license is appropriate for your use, or have questions regarding the use of this file,
  26.  * please contact AdroitLogic at info@adroitlogic.com
  27.  */
  28. /*
  29.  * Modificato da Link.it (https://link.it) per supportare le seguenti funzionalità:
  30.  * - firma e cifratura degli attachments
  31.  * - cifratura con chiave simmetrica
  32.  * - supporto CRL
  33.  *
  34.  * Copyright (c) 2011-2025 Link.it srl (https://link.it).
  35.  *
  36.  */
  37. package org.openspcoop2.security.message.soapbox;

  38. import java.security.cert.X509Certificate;
  39. import java.util.ArrayList;
  40. import java.util.HashSet;
  41. import java.util.List;

  42. import javax.xml.namespace.QName;
  43. import javax.xml.soap.AttachmentPart;
  44. import javax.xml.soap.SOAPElement;

  45. import org.adroitlogic.soapbox.CryptoUtil;
  46. import org.adroitlogic.soapbox.InvalidMessageDataException;
  47. import org.adroitlogic.soapbox.MessageSecurityContext;
  48. import org.adroitlogic.soapbox.Processor;
  49. import org.adroitlogic.soapbox.SBConstants;
  50. import org.adroitlogic.soapbox.SecurityConfig;
  51. import org.adroitlogic.soapbox.SecurityFailureException;
  52. import org.adroitlogic.soapbox.SignatureRequest;
  53. import org.apache.wss4j.common.WSS4JConstants;
  54. import org.openspcoop2.message.OpenSPCoop2SoapMessage;
  55. import org.openspcoop2.message.xml.MessageXMLUtils;
  56. import org.openspcoop2.security.message.constants.WSSAttachmentsConstants;
  57. import org.openspcoop2.utils.xml.AbstractXMLUtils;
  58. import org.w3c.dom.Document;
  59. import org.w3c.dom.Element;
  60. import org.w3c.dom.NamedNodeMap;
  61. import org.w3c.dom.Node;
  62. import org.w3c.dom.NodeList;


  63. /**
  64.  * SignPartialMessageProcessor
  65.  *
  66.  * Author of the original AdroitLogic code:
  67.  * @author asankha
  68.  *
  69.  * Authors of the Link.it modification to the code:
  70.  * @author Andrea Poli (apoli@link.it)
  71.  * @author Giovanni Bussu (bussu@link.it)
  72.  * @author $Author$
  73.  * @version $Rev$, $Date$
  74.  */
  75. public class SignPartialMessageProcessor implements Processor {

  76.     public static final QName TIMESTAMP = new QName(SBConstants.WSU, "Timestamp");
  77.    
  78.     protected List<QName> signQNames;
  79.     protected List<Boolean> elementsSignatureContent;
  80.     protected List<AttachmentPart> signAttachments;
  81.     protected OpenSPCoop2SoapMessage message;
  82.     public void setMessage(OpenSPCoop2SoapMessage message) {
  83.         this.message = message;
  84.     }
  85.     protected String actor;
  86.     protected boolean mustUnderstand;
  87.     public void setActor(String actor) {
  88.         this.actor = actor;
  89.     }
  90.     public void setMustUnderstand(boolean mustUnderstand) {
  91.         this.mustUnderstand = mustUnderstand;
  92.     }
  93.    
  94.     public SignPartialMessageProcessor() {
  95.         this.signQNames = new ArrayList<QName>();
  96.         this.signAttachments = new ArrayList<AttachmentPart>();
  97.         this.elementsSignatureContent = new ArrayList<Boolean>();
  98.     }
  99.    
  100.     public void addElementToSign(QName element , boolean content) {
  101.         this.signQNames.add(element);
  102.         this.elementsSignatureContent.add(content);
  103.     }
  104.    
  105.     public void addAttachmentsToSign(AttachmentPart part , boolean content) {
  106.         this.signAttachments.add(part);
  107.     }
  108.    
  109.     @Override
  110.     public void process(SecurityConfig secConfig, MessageSecurityContext msgSecCtx) {

  111.         AbstractXMLUtils xmlUtils = MessageXMLUtils.getInstance(this.message.getFactory());
  112.        
  113.         SignatureRequest signReq = msgSecCtx.getSignatureRequest();

  114.        // System.out.println("SIGN XMLSEC["+this.useXMLSec+"]");
  115.        
  116.        
  117.         // *** ensure existence of the wsse:Security header, and create one if none exists ***
  118.         Element wsseSecurityElem = null;
  119.         try{
  120.             wsseSecurityElem = WSSUtils.getWSSecurityHeader(msgSecCtx.getDocument(), this.actor, this.mustUnderstand);
  121.         }catch(Exception e){
  122.             throw new SecurityFailureException(e.getMessage(), e);
  123.         }
  124.        
  125.        
  126.        
  127.        
  128.         // *** we will not sign an already signed document ***
  129.         if (CryptoUtil.getFirstChildOrNull(wsseSecurityElem, SBConstants.DS, "Signature") != null) {
  130.             throw new InvalidMessageDataException("Message is already signed");
  131.         }

  132.        
  133.        
  134.    
  135.         // **** grab certificate used to sign, and find out the algorithm to be used ****
  136.         X509Certificate[] certs = secConfig.getCertificatesByAlias(signReq.getCertAlias());
  137.         String sigAlgoURI = signReq.getSignatureAlgoURI();
  138.         if (sigAlgoURI == null) {
  139.             if ("DSA".equalsIgnoreCase(certs[0].getPublicKey().getAlgorithm())) {
  140.                 sigAlgoURI = org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_DSA;
  141.             } else if ("RSA".equalsIgnoreCase(certs[0].getPublicKey().getAlgorithm())) {
  142.                 sigAlgoURI = org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_RSA;
  143.             } else {
  144.                 throw new SecurityFailureException("Signature algorithm not specified, and cannot be auto detected");
  145.             }
  146.         }

  147.        
  148.        
  149.        
  150.         // **** create XMLSignature engine ****
  151.         // NOTA:
  152.         // Vi sono fondamentalmente due versioni di XMLSignature con classi correlate.
  153.         // - com.sun.org.apache.xml.internal.security.signature: presente nel runtime di java
  154.         // - org.apache.xml.security.signature: presente in xmlsec-2.1.7.jar
  155.         //
  156.         // A seconda della versione utilizzata devono essere implementate delle classi a corredo:
  157.         // - com.sun.org.apache.xml.internal.security.transforms.TransformSpi implementato tramite org.openspcoop2.security.message.signature.SunAttachmentContentTransform
  158.         // - org.apache.xml.security.transforms.TransformSpi implementato tramite org.openspcoop2.security.message.signature.XMLSecAttachmentContentTransform
  159.         // NOTA: L'implementazione del Transformer tramite le classi della Sun cosi come realizzate usano metodi diversi presenti su Java 1.6 patch 26 o maggiore rispetto a Java 7.
  160.         //       Java 1.7 ha modificato i metodi della classe astratta com.sun.org.apache.xml.internal.security.transforms.TransformSpi
  161.         //       Il codice seguente e' stato scritto per poter effettuare i test incrociati sulle due versioni adeguando le classi utilizzate rispetto ad una variabile cablata nel codice
  162.         //       definita in org.openspcoop2.security.message.soapbox.MessageSecurityContext_soapbox.USE_XMLSEC_IMPL
  163.         //
  164.         // A seconda della versione utilizzata devono inoltre essere implementate le classe di risoluzione delle signature reference
  165.         // - com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverSpi implementata tramite org.openspcoop2.security.message.signature.SunEnvelopeIdResolver
  166.         // - org.apache.xml.security.utils.resolver.ResourceResolverSpi implementata tramite org.openspcoop2.security.message.signature.XMLSecEnvelopeIdResolver
  167.        
  168.         // NOTA: Tutto il discorso sopra e' terminato con java 11
  169.        
  170.         Document doc = msgSecCtx.getDocument();
  171.         Element env = doc.getDocumentElement();
  172.         org.apache.xml.security.signature.XMLSignature sigXMLSec = null;
  173.         if (org.apache.xml.security.c14n.Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS.equals(signReq.getC14nAlgoURI())) {
  174.             Element canonicalizationMethodElem = doc.createElementNS(SBConstants.DS, "ds:CanonicalizationMethod");
  175.             canonicalizationMethodElem.setAttribute("Algorithm", signReq.getC14nAlgoURI());
  176.              
  177.             try {
  178.                 org.apache.xml.security.algorithms.SignatureAlgorithm signatureAlgorithm = new org.apache.xml.security.algorithms.SignatureAlgorithm(doc, sigAlgoURI);
  179.                 sigXMLSec = new org.apache.xml.security.signature.XMLSignature(doc, null, signatureAlgorithm.getElement(), canonicalizationMethodElem);
  180.                 sigXMLSec.setId(SignPartialMessageProcessor.getSignId());
  181.             } catch (Exception e) {
  182.                 throw new SecurityFailureException("Error signing document with credentials of alias : " +
  183.                     signReq.getCertAlias() + " using algorithm : " + sigAlgoURI +
  184.                     " and c14n with : " + signReq.getC14nAlgoURI(), e);
  185.             }

  186.         } else {
  187.             try {
  188.                 sigXMLSec = new org.apache.xml.security.signature.XMLSignature(doc, null, sigAlgoURI, signReq.getC14nAlgoURI());
  189.                 sigXMLSec.setId(SignPartialMessageProcessor.getSignId());
  190.             } catch (Exception e) {
  191.                 throw new SecurityFailureException("Error signing document with credentials of alias : " +
  192.                     signReq.getCertAlias() + " using algorithm : " + sigAlgoURI +
  193.                     " and c14n with : " + signReq.getC14nAlgoURI(), e);
  194.             }
  195.         }

  196.        
  197.        
  198.        
  199.        
  200.        
  201.         // ** Definizione degli elementi da firmare **
  202.         // by default the elements to sign are the body and timestamp
  203.         if(this.signQNames.isEmpty() && this.signAttachments.isEmpty()) {
  204.             this.signQNames.add(new QName(env.getNamespaceURI(), "Body"));
  205.             this.elementsSignatureContent.add(false);
  206.             this.signQNames.add(SignPartialMessageProcessor.TIMESTAMP);
  207.             this.elementsSignatureContent.add(false);
  208.         }
  209.        
  210.         List<Element> signElements = new ArrayList<Element>();
  211.         List<Boolean> signTypeElements = new ArrayList<Boolean>();
  212.         for (int i = 0; i < this.signQNames.size(); i++) {
  213.             QName name = this.signQNames.get(i);
  214.             signElements.add(CryptoUtil.getFirstChild(env, name.getNamespaceURI(), name.getLocalPart()));
  215.             signTypeElements.add(this.elementsSignatureContent.get(i));
  216.         }
  217.        
  218.        
  219.         // ** Firma degli elementi indicati presenti nella SOAP Envelope **
  220.         signElements(signElements,signTypeElements, signReq, sigXMLSec);
  221.        
  222.        
  223.         // ** Firma degli attachments indicati **
  224.         sigXMLSec.addResourceResolver(org.openspcoop2.security.message.signature.XMLSecEnvelopeIdResolver.getInstance(this.message));
  225.         signAttachments(xmlUtils, this.signAttachments, signReq, sigXMLSec, doc);
  226.        
  227.        
  228.        
  229.         // ** Creazione del SignatureHeaderBlock e firma **
  230.         // NOTA:
  231.         // La creazione del SignatureHeaderBlock puo' essere gestita tramite una utility fornita dalla SunJava: com.sun.xml.wss.core.SignatureHeaderBlock
  232.         // tale classe richiede pero' l'utilizzo proprio della XMLSignature Engine della Sun.
  233.         // Altrimenti e' possibile agire direttamente tramite XMLSignature Engine in entrambe le soluzioni.
  234.         // Di seguito il boolean useSignatureHeaderBlock cablato nel codice serve proprio a switchare tra le due soluzioni
  235.        
  236.         Element signatureElem = null;
  237.            
  238.         try {
  239.                    
  240.             signatureElem = convertToSoapElement(sigXMLSec);
  241.            
  242.             if (signReq.isWsiBPCompliant()) {
  243.                 HashSet<String> prefixes = new HashSet<String>();
  244.                 prefixes.addAll(getInclusivePrefixes(signatureElem, false));
  245.                 Element canonicalizationMethodElem = (Element) signatureElem.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "CanonicalizationMethod").item(0);
  246.                 org.apache.xml.security.transforms.params.InclusiveNamespaces inclusiveNamespaces =
  247.                        new  org.apache.xml.security.transforms.params.InclusiveNamespaces(doc, prefixes);
  248.                 canonicalizationMethodElem.appendChild(inclusiveNamespaces.getElement());
  249.             }
  250.            
  251.             sigXMLSec.sign(secConfig.getPrivateKeyByAlias(signReq.getCertAlias()));
  252.             signatureElem = convertToSoapElement(sigXMLSec);
  253.            
  254.          } catch (Exception e) {
  255.             throw new SecurityFailureException("Error signing document using alias : " + signReq.getCertAlias(), e);
  256.         }
  257.        
  258.        
  259.        
  260.         // *** create and attach the keyinfo element ***
  261.         addKeyInfo(signatureElem, doc, signReq, msgSecCtx, secConfig, wsseSecurityElem);

  262.     }
  263.    
  264.    
  265.    
  266.     protected void addKeyInfo(Element signatureElem,Document doc,SignatureRequest signReq,MessageSecurityContext msgSecCtx,
  267.             SecurityConfig secConfig,Element wsseSecurityElem){
  268.         // //OLDMETHODCHENONGESTIVA ISSUER: signatureElem.appendChild(CryptoUtil.createKeyInfoElement(doc, signReq, msgSecCtx, secConfig));
  269.         signatureElem.appendChild(WSSUtils.createKeyInfoElement(doc, signReq, msgSecCtx, secConfig));
  270.         Element firstChild = CryptoUtil.getFirstElementChild(wsseSecurityElem);
  271.         if (firstChild != null) {
  272.             wsseSecurityElem.insertBefore(signatureElem, firstChild);
  273.         } else {
  274.             wsseSecurityElem.appendChild(signatureElem);
  275.         }

  276.         NodeList nl = wsseSecurityElem.getElementsByTagNameNS(SBConstants.WSSE, "BinarySecurityToken");
  277.         for (int i=0; i<nl.getLength(); i++) {
  278.             wsseSecurityElem.insertBefore(nl.item(i), signatureElem);
  279.         }
  280.     }
  281.    

  282.    
  283.     private Element convertToSoapElement(org.apache.xml.security.utils.ElementProxy proxy) {
  284.         org.w3c.dom.Element elem = proxy.getElement();
  285.         if(elem instanceof SOAPElement)
  286.             return elem;
  287.         return (Element) proxy.getDocument().importNode(elem, true);
  288.     }

  289.    
  290.    
  291.     /**
  292.      * Get the List of inclusive prefixes from the DOM Element argument
  293.      */
  294.     public List<String> getInclusivePrefixes(Element target, boolean excludeVisible) {
  295.         List<String> result = new ArrayList<>();
  296.         Node parent = target;
  297.         while (parent.getParentNode() != null &&
  298.             !(Node.DOCUMENT_NODE == parent.getParentNode().getNodeType())) {
  299.             parent = parent.getParentNode();
  300.             NamedNodeMap attributes = parent.getAttributes();
  301.             for (int i = 0; i < attributes.getLength(); i++) {
  302.                 Node attribute = attributes.item(i);
  303.                 if (WSS4JConstants.XMLNS_NS.equals(attribute.getNamespaceURI())) {
  304.                     if ("xmlns".equals(attribute.getNodeName())) {
  305.                         //System.out.println("FOUND #default per "+parent.getLocalName());
  306.                         result.add("#default");
  307.                     } else {
  308.                         //System.out.println("FOUND "+attribute.getLocalName()+" per "+parent.getLocalName());
  309.                         result.add(attribute.getLocalName());
  310.                     }
  311.                 }
  312.             }
  313.         }

  314.         //System.out.println("SIZE PRIMA EXCLUDE: "+result.size());
  315.        
  316.         if (excludeVisible == true) {
  317.             NamedNodeMap attributes = target.getAttributes();
  318.             for (int i = 0; i < attributes.getLength(); i++) {
  319.                 Node attribute = attributes.item(i);
  320.                 if (WSS4JConstants.XMLNS_NS.equals(attribute.getNamespaceURI())) {
  321.                     if ("xmlns".equals(attribute.getNodeName())) {
  322.                         //System.out.println("REMOVE #default per "+target.getLocalName());
  323.                         result.remove("#default");
  324.                     } else {
  325.                         //System.out.println("REMOVE "+attribute.getLocalName()+" per "+target.getLocalName());
  326.                         result.remove(attribute.getLocalName());
  327.                     }
  328.                 }
  329.                 if (attribute.getPrefix() != null) {
  330.                     //System.out.println("REMOVE PREFIX "+attribute.getPrefix()+" per "+target.getLocalName());
  331.                     result.remove(attribute.getPrefix());
  332.                 }
  333.             }

  334.             if (target.getPrefix() == null) {
  335.                 //System.out.println("REMOVE TARGET #default per "+target.getLocalName());
  336.                 result.remove("#default");
  337.             } else {
  338.                 //System.out.println("REMOVE TARGET PREFIX "+target.getPrefix()+" per "+target.getLocalName());
  339.                 result.remove(target.getPrefix());
  340.             }
  341.         }

  342.         //System.out.println("SIZE FINALE: "+result.size());
  343.        
  344.         return result;
  345.     }
  346.    
  347. //    protected void signAttachments(List<AttachmentPart> part, SignatureRequest signReq, SignatureHeaderBlock signatureHeaderBlock) throws Exception {
  348.     protected void signAttachments(AbstractXMLUtils xmlUtils,
  349.             List<AttachmentPart> part, SignatureRequest signReq,
  350.             org.apache.xml.security.signature.XMLSignature sigXMLSec,
  351.             Document d) {
  352.        
  353.         try {
  354.             // Specifica in Web Services Security SOAP Messages With Attachments (Swa) Profile 1.1
  355.             // 5.4.4 Processing Rules for Attachment Signing
  356.             // The processing rule for signing is modified based on the SOAP Message Security rules
  357.             // After determining which attachments are to be included as references in a signature, create a
  358.             // <ds:Signature> element in a <wsse:Security> header block targeted at the recipient, including a
  359.             // <ds:Reference> for each attachment to be protected by the signature. Additional <ds:Reference>
  360.             // elements may refer to content in the SOAP envelope to be included in the signature.
  361.            
  362.             // 1. MIME Part Canonicalize the content of the attachment, as appropriate to the MIME type of the part, as
  363.             // outlined in section 4.4.2 Attachments of an XML content type require Exclusive XML Canonicalization
  364.             // without comments[Excl-Canon].
  365.            
  366.             // 2. If MIME headers are to be included in the signature, perform MIME header canonicalization as
  367.             // outlined in section 4.4.1.
  368.            
  369.             //3. Determine the CID scheme URL to be used to reference the part and set the <ds:Reference> URL
  370.             // attribute value to this URL.
  371.            
  372.             // 4. Include a <ds:Transforms> element in the <ds:Reference>. This <ds:Transforms> element MUST
  373.             // include a <ds:Transform> element with the Algorithm attribute having the full URL value specified
  374.             // earlier in this profile – corresponding to either the Attachment-Complete-Signature-Transform or
  375.             // Attachment-Content-Signature-Transform, depending on what is to be included in the hash calculation.
  376.             // This MUST be the first transform listed. The <ds:Transform> element MUST NOT contain any
  377.             // transform for a MIME transfer encoding purpose (e.g. base64 encoding) since transfer encoding is left
  378.             // to the MIME layer as noted in section 2. This does not preclude the use of XML Transforms, including a
  379.             // base64 transform, for other purposes.
  380.            
  381.             // 5. Extract the appropriate portion of the MIME part consistent with the selected transform.
  382.            
  383.             // 6. Create the <ds:Reference> hash value as outlined in the W3C XML Digital Signature Recommendation.
  384.            
  385.             // For each attachment Reference, perform the following steps:
  386.             if(this.signAttachments==null || this.signAttachments.size()<=0){
  387.                 return;
  388.             }
  389.             for(AttachmentPart p : this.signAttachments){
  390.                
  391.                 String uri = p.getContentId();
  392.                 if (uri != null) {                
  393.                     if(uri.startsWith("<")){
  394.                         uri = "cid:" + uri.substring(1, uri.length()-1);
  395.                     }else{
  396.                         uri = "cid:" + uri;
  397.                     }
  398.                 } else {
  399.                     uri = p.getContentLocation();
  400.                 }
  401.                
  402.                 //Document d = this.message.getSOAPHeader().getOwnerDocument();
  403.                
  404.                 org.apache.xml.security.transforms.Transforms transforms =
  405.                         new org.apache.xml.security.transforms.Transforms(d);
  406.                 transforms.addTransform(WSSAttachmentsConstants.ATTACHMENT_CONTENT_SIGNATURE_TRANSFORM_URI);
  407.                
  408.                 String contentType = p.getContentType();
  409.                 if("text/xml".equals(contentType)){
  410.                     //transforms.addTransform(com.sun.org.apache.xml.internal.security.transforms.Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
  411.                     if (signReq.isWsiBPCompliant()) {
  412.                         byte[]raw = p.getRawContentBytes();
  413.                         Element signElement = xmlUtils.newElement(raw);
  414.                         transforms.item(0).getElement().appendChild(new org.apache.xml.security.transforms.params.InclusiveNamespaces(
  415.                                 d, CryptoUtil.getInclusivePrefixes(signElement, true)).getElement());
  416.                     }
  417.                 }
  418.                 /*else{
  419.                     transforms.addTransform(com.sun.org.apache.xml.internal.security.transforms.Transforms.TRANSFORM_BASE64_DECODE);
  420.                 }*/
  421.                
  422.                 sigXMLSec.addDocument(uri, transforms, signReq.getDigestAlgoURI());
  423.                
  424.                 //signatureHeaderBlock.addSignedInfoReference(uri, transforms, signReq.getDigestAlgoURI());
  425.                
  426. //              byte[]raw = p.getRawContentBytes();
  427. //              String contentType = p.getContentType();
  428. //              com.sun.org.apache.xml.internal.security.transforms.Transforms transforms =
  429. //                      new com.sun.org.apache.xml.internal.security.transforms.Transforms(d);
  430. //              
  431. //              // 1. MIME Part Canonicalize the content of the attachment, as appropriate to the MIME type of the part, as
  432. //              // outlined in section 4.4.2 Attachments of an XML content type require Exclusive XML Canonicalization
  433. //              // without comments[Excl-Canon].
  434. //              if("text/xml".equals(contentType)){
  435. //                  Element signElement = this.xmlUtils.newElement(raw);
  436. //                  transforms.addTransform(com.sun.org.apache.xml.internal.security.transforms.Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
  437. //                  if (signReq.isWsiBPCompliant()) {
  438. //                      transforms.item(0).getElement().appendChild(new InclusiveNamespaces(
  439. //                              signElement.getOwnerDocument(), CryptoUtil.getInclusivePrefixes(signElement, true)).getElement());
  440. //                  }
  441. //              }
  442. //              else{
  443. //                  Canonicalizer canonicalizer = CanonicalizerFactory.getCanonicalizer(contentType);
  444. //                  byte[] canonicalize = canonicalizer.canonicalize(raw);
  445. //                  transforms =
  446. //                          new com.sun.org.apache.xml.internal.security.transforms.Transforms(d);
  447. //                  transforms.addTransform(com.sun.org.apache.xml.internal.security.transforms.Transforms.TRANSFORM_BASE64_DECODE);
  448. //                  transforms.addBase64Text(Base64.encode(canonicalize));
  449. //              }
  450. //              
  451. //              // 2. If MIME headers are to be included in the signature, perform MIME header canonicalization as
  452. //              // outlined in section 4.4.1.
  453. //              // TODO
  454. //              
  455. //              //3. Determine the CID scheme URL to be used to reference the part and set the <ds:Reference> URL
  456. //              //attribute value to this URL.
  457. //              String uri = p.getContentId();
  458. //              if (uri != null) {                
  459. //                  uri = "cid:" + uri.substring(1, uri.length()-1);
  460. //              } else {
  461. //                  uri = p.getContentLocation();
  462. //              }
  463. //          
  464. //              // 4. Include a <ds:Transforms> element in the <ds:Reference>. This <ds:Transforms> element MUST
  465. //              // include a <ds:Transform> element with the Algorithm attribute having the full URL value specified
  466. //              // earlier in this profile – corresponding to either the Attachment-Complete-Signature-Transform or
  467. //              // Attachment-Content-Signature-Transform, depending on what is to be included in the hash calculation.
  468. //              // This MUST be the first transform listed. The <ds:Transform> element MUST NOT contain any
  469. //              // transform for a MIME transfer encoding purpose (e.g. base64 encoding) since transfer encoding is left
  470. //              // to the MIME layer as noted in section 2. This does not preclude the use of XML Transforms, including a
  471. //              // base64 transform, for other purposes.
  472. //              
  473. //              // 5. Extract the appropriate portion of the MIME part consistent with the selected transform.
  474. //              
  475. //              // 6. Create the <ds:Reference> hash value as outlined in the W3C XML Digital Signature Recommendation.
  476. //              
  477. //              signatureHeaderBlock.addSignedInfoReference(uri, transforms, signReq.getDigestAlgoURI());
  478.                
  479.             }
  480.         } catch(Exception e) {
  481.             throw new SecurityFailureException("Error signing attachments", e);
  482.         }
  483.        

  484.     }
  485.    
  486.     private void signElements(List<Element> signList,List<Boolean> signTypeList, SignatureRequest signReq,
  487.             org.apache.xml.security.signature.XMLSignature sigXMLSec) {    
  488.     //OLDMETHOD: private void signElements(List<Element> signList,List<Boolean> signTypeList, SignatureRequest signReq, XMLSignature sig) {
  489.      
  490.         for (int i = 0; i < signList.size(); i++) {
  491.            
  492.             Element signElement = signList.get(i);
  493.             @SuppressWarnings("unused")
  494.             Boolean content = signTypeList.get(i);

  495.             String signId = null;
  496.             try {
  497.                 signId = signElement.getAttributeNS(SBConstants.WSU, "Id");
  498.                 if (signId == null || signId.length() == 0) {
  499.                     signId = signElement.getAttribute("Id");
  500.                 }
  501.                 if (signId == null || signId.length() == 0) {
  502.                     signId = SignPartialMessageProcessor.getSignId();
  503.                     //signElement.setAttributeNS(SBConstants.WSU, "wsu:Id", signId);
  504.                     CryptoUtil.setWsuId(signElement,  signId);
  505.                 }

  506.                  org.apache.xml.security.transforms.Transforms transforms = new org.apache.xml.security.transforms.Transforms(signElement.getOwnerDocument());
  507.                  transforms.addTransform(org.apache.xml.security.transforms.Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
  508.                  //OLDMETHOD: Transforms transforms = new Transforms(signElement.getOwnerDocument());
  509.                 //OLDMETHOD: transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
  510.                  if (signReq.isWsiBPCompliant()) {

  511.                     transforms.item(0).getElement().appendChild(new org.apache.xml.security.transforms.params.InclusiveNamespaces(
  512.                          signElement.getOwnerDocument(), CryptoUtil.getInclusivePrefixes(signElement, true)).getElement());
  513.                    
  514.                  }
  515.                  sigXMLSec.addDocument("#" + signId, transforms, signReq.getDigestAlgoURI());

  516.             } catch (Exception e) {
  517.                 throw new SecurityFailureException("Error processing signature for element : {" +
  518.                     signElement.getNamespaceURI() + "}" + signElement.getLocalName() + " with Id : " + signId, e);
  519.             }
  520.         }
  521.     }
  522.    
  523.    
  524.     public static String getSignId(){
  525.         //return CryptoUtil.getRandomId();
  526.         return MessageSecurityContext_soapbox.getWsuIdAllocator().createId(CryptoUtil.getRandomId(), null);
  527.     }
  528. }