Package org.jboss.identity.federation.api.util

Source Code of org.jboss.identity.federation.api.util.XMLSignatureUtil

/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.identity.federation.api.util;

import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Collections;
import java.util.List;

import javax.security.cert.X509Certificate;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.jboss.identity.federation.core.saml.v2.util.DocumentUtil;
import org.jboss.identity.federation.core.util.JAXBUtil;
import org.jboss.identity.xmlsec.w3.xmldsig.ObjectFactory;
import org.jboss.identity.xmlsec.w3.xmldsig.SignatureType;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
* Utility for XML Signature
* @author Anil.Saldhana@redhat.com
* @since Dec 15, 2008
*/
public class XMLSignatureUtil
{
   private static String pkgName = "org.jboss.identity.federation.w3.xmldsig";
   private static String schemaLocation = "schema/saml/v2/xmldsig-core-schema.xsd";
  
   private static ObjectFactory objectFactory = new ObjectFactory();
  
   private static XMLSignatureFactory fac =  getXMLSignatureFactory();
  
   private static XMLSignatureFactory getXMLSignatureFactory()
   {
      XMLSignatureFactory xsf =   null;
     
      try
      {
         xsf = XMLSignatureFactory.getInstance("DOM");
      }
      catch(Exception err)
      {
         //JDK5
         xsf = XMLSignatureFactory.getInstance("DOM",
               new org.jcp.xml.dsig.internal.dom.XMLDSigRI());
      }
      return xsf;
   }
  
   /**
    * Sign a node in a document
    * @param doc Document
    * @param parentOfNodeToBeSigned Parent Node of the node to be signed
    * @param signingKey Private Key
    * @param certificate X509 Certificate holding the public key
    * @param digestMethod (Example: DigestMethod.SHA1)
    * @param signatureMethod (Example: SignatureMethod.DSA_SHA1)
    * @param referenceURI
    * @return Document that contains the signed node
    * @throws XMLSignatureException
    * @throws MarshalException
    * @throws GeneralSecurityException
    * @throws ParserConfigurationException 
    */
   public static Document sign(Document doc,
          Node parentOfNodeToBeSigned,
          PrivateKey signingKey,
          X509Certificate certificate,
          String digestMethod,
          String signatureMethod,
          String referenceURI)
   throws ParserConfigurationException, GeneralSecurityException, MarshalException, XMLSignatureException
   {
      KeyPair keyPair = new KeyPair(certificate.getPublicKey(),signingKey);
      return sign(doc,parentOfNodeToBeSigned, keyPair,
            digestMethod, signatureMethod, referenceURI);
   }
  
   /**
    * Sign a node in a document
    * @param doc
    * @param nodeToBeSigned
    * @param keyPair
    * @param publicKey
    * @param digestMethod
    * @param signatureMethod
    * @param referenceURI
    * @return
    * @throws ParserConfigurationException 
    * @throws XMLSignatureException
    * @throws MarshalException
    * @throws GeneralSecurityException
    */ 
   public static Document sign(Document doc,
         Node nodeToBeSigned,
         KeyPair keyPair,
         String digestMethod,
         String signatureMethod,
         String referenceURI) throws ParserConfigurationException, GeneralSecurityException, MarshalException, XMLSignatureException
   {
      if(nodeToBeSigned == null)
         throw new IllegalArgumentException("Node to be signed is null");
      //Let us create a new Document
      Document newDoc = DocumentUtil.createDocument();
      //Import the node
      Node signingNode = newDoc.importNode(nodeToBeSigned, true);
      newDoc.appendChild(signingNode);
     
      newDoc = sign(newDoc, keyPair, digestMethod, signatureMethod, referenceURI);
     
      //Now let us import this signed doc into the original document we got in the method call
      Node signedNode = doc.importNode(newDoc.getFirstChild(), true);
     
      doc.getDocumentElement().replaceChild(signedNode, nodeToBeSigned);
     
      return doc;
   }
  
  
   /**
    * Sign the root element
    * @param doc
    * @param signingKey
    * @param publicKey
    * @param digestMethod
    * @param signatureMethod
    * @param referenceURI
    * @return
    * @throws GeneralSecurityException 
    * @throws XMLSignatureException
    * @throws MarshalException
    */
   public static Document sign(Document doc,
         KeyPair keyPair,
         String digestMethod,
         String signatureMethod,
         String referenceURI) throws GeneralSecurityException, MarshalException, XMLSignatureException
  {  
     PrivateKey signingKey = keyPair.getPrivate();
     PublicKey publicKey = keyPair.getPublic();
     
     DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement());  
//     dsc.putNamespacePrefix(XMLSignature.XMLNS, "ds");
    
     DigestMethod digestMethodObj = fac.newDigestMethod(digestMethod, null);
     Transform transform = fac.newTransform(Transform.ENVELOPED,
           (TransformParameterSpec) null);
    
     List<Transform> transformList = Collections.singletonList(transform);
     Reference ref = fac.newReference
       ( referenceURI, digestMethodObj,transformList,null, null);
    
     String canonicalizationMethodType = CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS;
     CanonicalizationMethod canonicalizationMethod
         = fac.newCanonicalizationMethod
         (canonicalizationMethodType, (C14NMethodParameterSpec) null);
    
     List<Reference> referenceList = Collections.singletonList(ref);
     SignatureMethod signatureMethodObj = fac.newSignatureMethod(signatureMethod, null);
     SignedInfo si =  fac.newSignedInfo (canonicalizationMethod, signatureMethodObj ,
                             referenceList)
    
     KeyInfoFactory kif = fac.getKeyInfoFactory();
     KeyValue kv = kif.newKeyValue(publicKey);
     KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));

     XMLSignature signature = fac.newXMLSignature(si, ki);

     signature.sign(dsc);
    
     return doc;
  }
   /**
    * Validate a signed document with the given public key
    * @param signedDoc
    * @param publicKey
    * @return
    * @throws MarshalException
    * @throws XMLSignatureException
    */
   public static boolean validate(Document signedDoc, Key publicKey) throws MarshalException, XMLSignatureException
   {
      NodeList nl = signedDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
      if (nl == null || nl.getLength() == 0)
      {
        throw new IllegalArgumentException("Cannot find Signature element");
      }
      DOMValidateContext valContext = new DOMValidateContext(publicKey, nl.item(0));
      XMLSignature signature =  fac.unmarshalXMLSignature(valContext);
      boolean coreValidity = signature.validate(valContext);

      return coreValidity;
   }
   /**
    * Marshall a SignatureType to output stream
    * @param signature
    * @param os
    * @throws SAXException
    * @throws JAXBException
    */
   public static void marshall(SignatureType signature, OutputStream os) throws JAXBException, SAXException
   {
      JAXBElement<SignatureType> jsig = objectFactory.createSignature(signature);
      Marshaller marshaller = JAXBUtil.getValidatingMarshaller(pkgName, schemaLocation);
      marshaller.marshal(jsig, os);
   }
   /**
    * Marshall the signed document to an output stream
    * @param signedDocument
    * @param os
    * @throws TransformerException
    */
   public static void marshall(Document signedDocument, OutputStream os)
   throws TransformerException
   {
      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer trans = tf.newTransformer();
      trans.transform(new DOMSource(signedDocument), new StreamResult(os));
   }
}
TOP

Related Classes of org.jboss.identity.federation.api.util.XMLSignatureUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.