You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@santuario.apache.org by bu...@apache.org on 2003/12/14 09:50:19 UTC

DO NOT REPLY [Bug 25509] New: - Signature veryfication fails when used with SAML

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: security-dev@xml.apache.org
        ReportedBy: deepak@linuxquestions.net


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");
	}

}