Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WSS1721: Validation of Reference with URI #XWSSGID-XXXXXXXXXXXX-YYYYYYY failed for a correctly signed message #381

Open
Tomas-Kraus opened this issue Jun 2, 2022 · 0 comments

Comments

@Tomas-Kraus
Copy link
Member

Metro manages to produce digitally signed messages that it cannot successfully validate.
Signature validation fails with the following error message:
WSS1721: Validation of Reference with URI #XWSSGID-XXXXXXXXXXXX-YYYYYYY failed

Steps to reproduce:

1. Add the following test case to <checked_out_sources>/wssx-impl/src/test/java/com/sun/xml/wss/impl: SignTest1.java, see source code below.
The test case is actually a slightly modified version of SignSOAPHeadersOnlyTest.java from the same package.

2. Run the test, and it will fail with the following exception:
com.sun.xml.wss.impl.WssSoapFaultException: Invalid Security Header
at com.sun.xml.ws.security.opt.impl.util.SOAPUtil.newSOAPFaultException(SOAPUtil.java:159)
at com.sun.xml.ws.security.opt.impl.incoming.processor.SignedInfoProcessor.processReference(SignedInfoProcessor.java:429)
at com.sun.xml.ws.security.opt.impl.incoming.Signature.isReady(Signature.java:415)
at com.sun.xml.ws.security.opt.impl.incoming.Signature.validate(Signature.java:372)
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.handleSignature(SecurityRecipient.java:1305)
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.createMessage(SecurityRecipient.java:832)
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.validateMessage(SecurityRecipient.java:252)
at com.sun.xml.wss.impl.SignTest1.verify(SignTest1.java:250)
at com.sun.xml.wss.impl.SignTest1.test1Test(SignTest1.java:186)
...
at junit.framework.TestSuite.run(TestSuite.java:225)

Note that it fails to verify the signature of JAX-WS message. Right before that the same SOAP message is successfully validated as a SAAJ SOAPMessage (SignTest1.java:183)

3. Modify the test, remove comment on lines 102 and 109:
// st.addTransform(new SignatureTarget.Transform(MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS));

4. Run the test again, and it is green.

Expected behavior: the test should pass even if addTransform() is not invoked. After all, these lines have no effect on validating a SAAJ SOAPMessage.

Cause: class com.sun.xml.ws.security.opt.crypto.dsig.Reference, method
private byte[] transform(Data dereferencedData, XMLCryptoContext context)

Nothing is written to the DigesterOutputStream if there are no any Transforms in the incoming message.
And I guess the same error can happen even if there are Transforms in the incoming message. At least method
public Data transform(Data data, XMLCryptoContext xMLCryptoContext, OutputStream outputStream) of class com.sun.xml.ws.security.opt.crypto.dsig.Transform can return non-null Data instances under some conditions.

Source code:

package com.sun.xml.wss.impl;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.security.auth.callback.CallbackHandler;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

import com.sun.xml.stream.buffer.XMLStreamBuffer;
import com.sun.xml.stream.buffer.XMLStreamBufferMark;
import com.sun.xml.stream.buffer.stax.StreamReaderBufferProcessor;
import com.sun.xml.ws.api.SOAPVersion;
import com.sun.xml.ws.api.message.Message;
import com.sun.xml.ws.encoding.StreamSOAPCodec;
import com.sun.xml.ws.message.stream.StreamMessage;
import com.sun.xml.ws.policy.AssertionSet;
import com.sun.xml.ws.policy.Policy;
import com.sun.xml.ws.policy.PolicyAssertion;
import com.sun.xml.ws.security.opt.impl.JAXBFilterProcessingContext;
import com.sun.xml.ws.security.policy.AlgorithmSuiteValue;
import com.sun.xml.wss.SecurityEnvironment;
import com.sun.xml.wss.callback.PolicyCallbackHandler1;
import com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl;
import com.sun.xml.wss.impl.policy.mls.AuthenticationTokenPolicy;
import com.sun.xml.wss.impl.policy.mls.MessagePolicy;
import com.sun.xml.wss.impl.policy.mls.SignaturePolicy;
import com.sun.xml.wss.impl.policy.mls.SignatureTarget;
import com.sun.xml.wss.impl.policy.mls.Target;
import com.sun.xml.wss.impl.util.PolicyResourceLoader;
import com.sun.xml.wss.impl.util.TestUtil;

/**
*

private static HashMap client = new HashMap();
private static HashMap server = new HashMap();
private static AlgorithmSuite alg = null;

/** Creates a new instance of SignAllHeadersTest */
public SignTest1(String testName)

{ super(testName); }

protected void setUp() throws Exception {
ConsoleHandler handler = new ConsoleHandler();

handler.setLevel(Level.FINEST);

for (String s : new String[]

{"com.sun.xml.wss", "javax.enterprise.resource.xml.webservices.security"}

)

{ Logger logger = Logger.getLogger(s); logger.setLevel(Level.FINEST); logger.addHandler(handler); logger.finest("aaaaaa: " + s); }

}

protected void tearDown() throws Exception {
}

public static Test suite()

{ return new TestSuite(SignTest1.class); }

public static void test1Test() throws Exception {
// alg.setType(AlgorithmSuiteValue.Basic128);
alg = new AlgorithmSuite(AlgorithmSuiteValue.Basic128.getDigAlgorithm(),
AlgorithmSuiteValue.Basic128.getEncAlgorithm(),
AlgorithmSuiteValue.Basic128.getSymKWAlgorithm(),
AlgorithmSuiteValue.Basic128.getAsymKWAlgorithm());

SignaturePolicy signaturePolicy = new SignaturePolicy();
SignaturePolicy.FeatureBinding fb = (SignaturePolicy.FeatureBinding)signaturePolicy.getFeatureBinding();

SignatureTarget st = new SignatureTarget();

st.setType(Target.TARGET_TYPE_VALUE_URI);
st.setValue(Target.ALL_MESSAGE_HEADERS);
st.setDigestAlgorithm(DigestMethod.SHA1);
// st.addTransform(new SignatureTarget.Transform(MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS));
fb.addTargetBinding(st);

st = new SignatureTarget();
st.setType(Target.TARGET_TYPE_VALUE_QNAME);
st.setValue(Target.BODY);
st.setDigestAlgorithm(DigestMethod.SHA1);
// st.addTransform(new SignatureTarget.Transform(MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS));
fb.addTargetBinding(st);

fb.setCanonicalizationAlgorithm(MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);

// QName name = new QName("X509Certificate");
// Token tok = new Token(name);
//
AuthenticationTokenPolicy.X509CertificateBinding x509bind =
(AuthenticationTokenPolicy.X509CertificateBinding)signaturePolicy.newX509CertificateKeyBinding();
x509bind.setReferenceType(MessageConstants.DIRECT_REFERENCE_TYPE);
// //x509bind.setPolicyToken(tok);
x509bind.setUUID(new String("1004"));

// create SOAPMessage
SOAPMessage msg = MessageFactory.newInstance().createMessage();
SOAPHeader header = msg.getSOAPHeader();
SOAPHeaderElement she1 = header.addHeaderElement(SOAPFactory.newInstance().createName("StockHeader","stkheader","http://stockhome.com/quote"));
she1.addTextNode("Head Text Node1");
SOAPHeaderElement she2 = header.addHeaderElement(SOAPFactory.newInstance().createName("Quote","quote","http://stockhome.com/quote"));
she2.addTextNode("Head Text Node2");
header.addTextNode("\n ");
SOAPBody body = msg.getSOAPBody();
msg.getSOAPPart().getDocumentElement().insertBefore(msg.getSOAPPart().createTextNode("\n "), body);
body.addTextNode("\n ");
SOAPBodyElement sbe = body.addBodyElement(
SOAPFactory.newInstance().createName(
"StockSymbol",
"tru",
"http://fabrikam123.com/payloads"));
sbe.addTextNode("QQQ");
body.addTextNode("\n ");

//Create processing context and set the soap message to be processed.
ProcessingContextImpl context = new ProcessingContextImpl(client);

context.setSOAPMessage(msg);

com.sun.xml.ws.security.policy.WSSAssertion wssAssertionws = null;
WSSAssertion wssAssertion = null;
AssertionSet as = null;
Policy wssPolicy = new PolicyResourceLoader().loadPolicy("security/policy-binding1.xml");
Iterator i = wssPolicy.iterator();
if(i.hasNext())
as = i.next();

for(PolicyAssertion assertion:as){
if(assertion instanceof com.sun.xml.ws.security.policy.WSSAssertion)

{ wssAssertionws = (com.sun.xml.ws.security.policy.WSSAssertion)assertion; }
}
wssAssertion = new WSSAssertion(wssAssertionws.getRequiredProperties(), "1.0");
MessagePolicy pol = new MessagePolicy();
pol.append(signaturePolicy);
pol.setWSSAssertion(wssAssertion);

context.setAlgorithmSuite(alg);
context.setSecurityPolicy(pol);
CallbackHandler handler = new PolicyCallbackHandler1("client");
SecurityEnvironment env = new DefaultSecurityEnvironmentImpl(handler);
context.setSecurityEnvironment(env);
SecurityAnnotator.secureMessage(context);

SOAPMessage secMsg = context.getSOAPMessage();
//DumpFilter.process(context);

// now persist the message and read-back
FileOutputStream sentFile = new FileOutputStream("golden.msg");
secMsg.saveChanges();
TestUtil.saveMimeHeaders(secMsg, "golden.mh");
secMsg.writeTo(sentFile);
sentFile.close();

// verify as SOAPMessage
verify("golden.mh", "golden.msg");

// verify as JAX-WS Message
verify(null, "golden.msg");
}

public static void verify(String mimeHdrsFile, String msgFile) throws Exception {
com.sun.xml.ws.security.policy.WSSAssertion wssAssertionws = null;
WSSAssertion wssAssertion = null;
AssertionSet as = null;
Policy wssPolicy = new PolicyResourceLoader().loadPolicy("security/policy-binding2.xml");
Iterator i = wssPolicy.iterator();
if(i.hasNext())
as = i.next();

for(PolicyAssertion assertion:as){
if(assertion instanceof com.sun.xml.ws.security.policy.WSSAssertion){ wssAssertionws = (com.sun.xml.ws.security.policy.WSSAssertion)assertion; }

}
//wssAssertion.addRequiredProperty("RequireSignatureConfirmation");
wssAssertion = new WSSAssertion(wssAssertionws.getRequiredProperties(), "1.0");

MessagePolicy pol = new MessagePolicy();

pol.setWSSAssertion(wssAssertion);

if (mimeHdrsFile != null)

{ SOAPMessage recMsg = TestUtil.constructMessage(mimeHdrsFile, msgFile); //Create processing context and set the soap message to be processed. ProcessingContextImpl context = new ProcessingContextImpl(); context.setSOAPMessage(recMsg); context.setSecurityPolicy(pol); context.setAlgorithmSuite(alg); CallbackHandler handler = new PolicyCallbackHandler1("server"); SecurityEnvironment env = new DefaultSecurityEnvironmentImpl(handler); context.setSecurityEnvironment(env); SecurityRecipient.validateMessage(context); }

else

{ FileInputStream fis = new FileInputStream(msgFile); XMLReader xr = XMLReaderFactory.createXMLReader(); xr.setFeature("http://xml.org/sax/features/namespaces", true); XMLStreamBuffer xb = XMLStreamBuffer.createNewBufferFromXMLReader(xr, fis); StreamReaderBufferProcessor xp = xb.readAsXMLStreamReader(); XMLStreamBufferMark mark = new XMLStreamBufferMark(null, xp); StreamSOAPCodec sc = StreamSOAPCodec.create(SOAPVersion.SOAP_11); Message soapMsg = sc.decode(xp); JAXBFilterProcessingContext context = new JAXBFilterProcessingContext(null, pol, soapMsg, SOAPVersion.SOAP_11); context.setAlgorithmSuite(alg); CallbackHandler handler = new PolicyCallbackHandler1("server"); SecurityEnvironment env = new DefaultSecurityEnvironmentImpl(handler); context.setSecurityEnvironment(env); com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient sr = new com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient(mark.readAsXMLStreamReader(), SOAPVersion.SOAP_11); sr.setBodyPrologue(((StreamMessage)soapMsg).getBodyPrologue()); sr.setBodyEpilogue(((StreamMessage)soapMsg).getBodyEpilogue()); sr.validateMessage(context); }

//System.out.println("Verfied Message");
//DumpFilter.process(context);
}
}

Affected Versions

[2.3]

Source: javaee/metro-wsit#1673
Author: glassfishrobot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant