DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=25509>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=25509

Signature veryfication fails when used with SAML

           Summary: Signature veryfication fails when used with SAML
           Product: Security
           Version: unspecified
          Platform: PC
        OS/Version: Windows NT/2K
            Status: NEW
          Severity: Major
          Priority: Other
         Component: Signature
        AssignedTo: [EMAIL PROTECTED]
        ReportedBy: [EMAIL PROTECTED]


In xml-security 1.5D2 version while trying to veryfy a soap message which is 
signed previously is getting failed if it contains any SAML elements in the 
header. Otherwise the verification is getting success. The sample java code for 
veyfication is given bello.It uses RSA algorithm.


import java.io.InputStream;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.log4j.Logger;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.utils.Constants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * This adapter is used for verify the signature in the SOAP envelope
 * header using a pre distributed RSA based certificate   
 */
public class SignatureVerificationHandler extends BasicHandler {

        /** Name of the handler option used for configuring the certificate.
         *  This parameter is mandatory.
        */
        public static final String CERTIFICATE_OPTION_NAME = "soaCerificate";
        /** Name of the handler option used for configuring the certificate.
         *  This parameter is mandatory.
        */
        public static final String CERTIFICATE_TYPE_OPTION_NAME =
                "soaCertificateType";
        /** Certificate value **/
        private Certificate cert = null;

        public static final Logger myLogger =
                Logger.getLogger(WSSignatureVerificationAdapter.class);

        // Initializing the xml-security
        static {
                org.apache.xml.security.Init.init();
        }

        /** Certificate file is loaded and the certificate value and the public 
key
         *  are extracted from the file  
         * 
        */
        public void init() {

                myLogger.debug("Initializing WSSignatureVerificationAdapter");
                List missingParams = new LinkedList();
                //Reading the certificate location option
                String certFile = (String) getOption(CERTIFICATE_OPTION_NAME);
                if (certFile == null) {
                        missingParams.add(CERTIFICATE_OPTION_NAME);
                }
                String certType = (String) getOption
(CERTIFICATE_TYPE_OPTION_NAME);
                if (certType == null) {
                        missingParams.add(CERTIFICATE_TYPE_OPTION_NAME);
                }
                
                //If any of the options are missing throws Exception
                if (!missingParams.isEmpty()) {
                        StringBuffer errMsgBuffer =
                                new StringBuffer("Following mandatory filed(s) 
are missing:");
                        Iterator i = missingParams.iterator();
                        while (i.hasNext()) {
                                errMsgBuffer.append(' ');
                                errMsgBuffer.append((String) i.next());
                        }
                        String errMsg = errMsgBuffer.toString();
                        myLogger.fatal(errMsg);
                        throw new RuntimeException(errMsg);
                }
                
                //Loading the certificate 
                try {
                        InputStream certis =
                        
        WSSignatureVerificationAdapter.class.getResourceAsStream(
                                        certFile);

                        CertificateFactory cf = CertificateFactory.getInstance
(certType);
                        cert = cf.generateCertificate(certis);
                        myLogger.debug("Certificate loaded successfully");
                        myLogger.debug(
                                "WSSignatureVerificationAdapter initialized 
successfully");
                } catch (Exception initExp) {
                        String errMsg = "Exception while reading Certificate";
                        myLogger.fatal(errMsg, initExp);
                        throw new RuntimeException(errMsg, initExp);
                }
        }
        /** 
         * Verify the SOAP request message with the public key in the 
certificate  
        */
        public void invoke(MessageContext msgContext) throws AxisFault {

                myLogger.debug("invoke()d WSSignatureVerificationAdapter");

                //Getting the SOAP message document       
                Message message = msgContext.getRequestMessage();
                SOAPEnvelope soapEnvelope = message.getSOAPEnvelope();
                myLogger.debug("SOAP Envelope got successfully");
                try {
                        //convert to dom so that we can use for signature 
verification
                        Document doc = soapEnvelope.getAsDocument();
                        Element sigElement = null;
                        NodeList nodes =
                                doc.getElementsByTagNameNS(
                                        Constants.SignatureSpecNS,
                                        WSConstants.WS_XML_SECURITY_SIGN_TAG);
                                        
                        //Getting the signature element and verifying
                        if (nodes.getLength() != 0) {
                                myLogger.debug(
                                        "Found " + nodes.getLength() + " 
Signature elements.");
                                sigElement = (Element) nodes.item(0);
                                XMLSignature signature = new XMLSignature
(sigElement, "");
                                myLogger.debug("The signature value got:" + 
signature.getSignedInfo().getCanonicalizationMethodURI());
                                //If the signature is not valid one then 
throwing an exception                              
                                if (!signature.checkSignatureValue
(cert.getPublicKey())) {
                                        String errMsg = "The XML Signature is 
Invalid";
                                        myLogger.error(errMsg);
                                        throw new AxisFault(errMsg);
                                }
                        } //The node.getLength is 0, so there is no signature
                        else {
                                String errMsg = "The Request is not Signed";
                                myLogger.error(errMsg);
                                throw new AxisFault(errMsg);
                        }

                } catch (Exception e) {
                        myLogger.error("Exception when verifying SOAPEnvelope", 
e);
                        AxisFault f;
                        if (e instanceof AxisFault) {
                                f = (AxisFault) e;
                        } else {
                                f = AxisFault.makeFault(e);
                        }
                        throw f;
                }
                //The signature is valid so allowed to pass 
                myLogger.debug("The XML Signature is Valid");
                myLogger.debug("WSSignatureVerificationAdapter invoke()d 
successfully");
        }

}

Reply via email to