[ 
https://issues.apache.org/jira/browse/WSS-618?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16251524#comment-16251524
 ] 

J.Cranendonk commented on WSS-618:
----------------------------------

Hi!

Thank you very much for your effort! I have tried the new code, sadly it 
doesn't work yet..
The stack trace is at the end of the comment, I think what is happening is that 
your addition is to WSSecSignature.build(Crypto cr).
Based on the comment on the code this is an older method no longer used, if I 
look at the stack trace, this now flows through SignatureAction.execute(...),
where there is a similar code block (look for "STRTransform").

I've tried to apply the same code to SignatureAction in an ugly way :) Which 
seems to mostly work!
I've added a patch for that below the stack trace :)

The only problem I now run into is that in verifying I get a complaint about 
"org.apache.wss4j.common.ext.WSSecurityException: Referenced security token 
could not be retrieved".

Looking at the XML I see this:
          <wsse:SecurityTokenReference 
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
 
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
 *wsu:Id="STR-f0836798-d1fb-4b4c-a92f-60c5dfae811b"*>
I think what might happen is that the STR-.. id is replaced on KeyInfo or so? I 
have no idea what the STR id is or why it's there tbh. :)

{noformat}
14-11-2017 15:50:21.192 [SimpleAsyncTaskExecutor-1] WARN      
 o.a.cxf.phase.PhaseInterceptorChain.doLog - Interceptor for 
{urn:nl-gdi-eid:1.0:webservices}BSNKActivatePortService#{urn:nl-gdi-eid:1.0:webservices}BSNK_ProvidePP_PPCAOptimized
 has thrown exception, unwinding now
org.apache.cxf.binding.soap.SoapFault: Security processing failed.
        at 
org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessageInternal(WSS4JOutInterceptor.java:272)
        at 
org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:136)
        at 
org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:123)
        at 
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
        at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
        at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
        at 
org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
        at com.sun.proxy.$Proxy125.bsnkProvidePPPPCAOptimized(Unknown Source)
        at 
com.idemia.efunc.ih.bsnk.ws.BsnkWebServiceClient.send(BsnkWebServiceClient.java:89)
        at sun.reflect.GeneratedMethodAccessor58.invoke(Unknown Source)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at 
org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:113)
        at 
org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:102)
        at 
org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49)
        at 
org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:347)
        at 
org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88)
        at 
org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131)
        at 
org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:360)
        at 
org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:169)
        at 
org.springframework.integration.util.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:319)
        at 
org.springframework.integration.util.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:155)
        at 
org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:93)
        at 
org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:89)
        at 
org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
        at 
org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
        at 
org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
        at 
org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
        at 
org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
        at 
org.springframework.integration.amqp.channel.AbstractSubscribableAmqpChannel$DispatchingMessageListener.onMessage(AbstractSubscribableAmqpChannel.java:293)
        at 
org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:891)
        at 
org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:782)
        at 
org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:102)
        at 
org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:198)
        at 
org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1311)
        at 
org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:752)
        at 
org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1254)
        at 
org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1224)
        at 
org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:102)
        at 
org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1470)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Error during 
Signature: 
        at 
org.apache.wss4j.dom.action.SignatureAction.execute(SignatureAction.java:163)
        at 
org.apache.wss4j.dom.handler.WSHandler.doSenderAction(WSHandler.java:238)
        at 
org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor.access$100(WSS4JOutInterceptor.java:55)
        at 
org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessageInternal(WSS4JOutInterceptor.java:264)
        ... 43 common frames omitted
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Cannot setup 
signature data structure
        at 
org.apache.wss4j.dom.message.WSSecSignatureBase.addReferencesToSign(WSSecSignatureBase.java:220)
        at 
org.apache.wss4j.dom.message.WSSecSignature.addReferencesToSign(WSSecSignature.java:424)
        at 
org.apache.wss4j.dom.action.SignatureAction.execute(SignatureAction.java:149)
        ... 46 common frames omitted
Caused by: org.apache.wss4j.common.ext.WSSecurityException: Element to 
encrypt/sign not found: http://www.w3.org/2000/09/xmldsig#, KeyInfo
        at 
org.apache.wss4j.dom.message.WSSecSignatureBase.addReferencesToSign(WSSecSignatureBase.java:184)
        ... 48 common frames omitted
{noformat}


{noformat}
Index: src/main/java/org/apache/wss4j/dom/action/SignatureAction.java
===================================================================
--- src/main/java/org/apache/wss4j/dom/action/SignatureAction.java      
(revision 1815207)
+++ src/main/java/org/apache/wss4j/dom/action/SignatureAction.java      
(working copy)
@@ -24,6 +24,9 @@

 import javax.security.auth.callback.CallbackHandler;

+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dom.DOMCryptoContext;
+
 import org.apache.wss4j.common.SecurityActionToken;
 import org.apache.wss4j.common.SignatureActionToken;
 import org.apache.wss4j.common.WSEncryptionPart;
@@ -34,6 +37,7 @@
 import org.apache.wss4j.dom.handler.WSHandler;
 import org.apache.wss4j.dom.message.WSSecSignature;
 import org.apache.wss4j.dom.util.WSSecurityUtil;
+import javax.xml.crypto.dom.DOMStructure;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -109,6 +113,21 @@
             for (WSEncryptionPart part : signatureToken.getParts()) {
                 if ("STRTransform".equals(part.getName()) && part.getId() == 
null) {
                     part.setId(wsSign.getSecurityTokenReferenceURI());
+                } else if ("KeyInfo".equals(part.getName()) && 
WSConstants.SIG_NS.equals(part.getNamespace())
+                    && part.getElement() == null) {
+                    // Special code to sign the KeyInfo - we have to marshal 
the KeyInfo to a DOM Element
+                    // before the signing process
+                    Element parent = 
wsSign.getSecurityTokenReference().getElement().getOwnerDocument().createElement
+                    DOMCryptoContext cryptoContext = new DOMCryptoContext() {
+                    };
+                    cryptoContext.putNamespacePrefix(WSConstants.SIG_NS, 
WSConstants.SIG_PREFIX);
+                    try {
+                        wsSign.getKeyInfo().marshal(new DOMStructure(parent), 
cryptoContext);
+                    } catch (MarshalException ex) {
+                        //LOG.error(ex.getMessage(), ex);
+                        throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, ex);
+                    }
+                    part.setElement((Element) parent.getFirstChild());
                 } else if (reqData.isAppendSignatureAfterTimestamp()
                         && WSConstants.WSU_NS.equals(part.getNamespace())
                         && "Timestamp".equals(part.getName())) {
Index: src/main/java/org/apache/wss4j/dom/message/WSSecSignature.java
===================================================================
--- src/main/java/org/apache/wss4j/dom/message/WSSecSignature.java      
(revision 1815207)
+++ src/main/java/org/apache/wss4j/dom/message/WSSecSignature.java      
(working copy)
@@ -121,7 +121,9 @@
         super(doc);
         init(provider);
     }
-
+public KeyInfo getKeyInfo() {
+     return keyInfo;
+}
     private void init(Provider provider) {
         if (provider == null) {
             // Try to install the Santuario Provider - fall back to the JDK 
provider if this does

{noformat}


> Cannot create signature which includes KeyInfo
> ----------------------------------------------
>
>                 Key: WSS-618
>                 URL: https://issues.apache.org/jira/browse/WSS-618
>             Project: WSS4J
>          Issue Type: Bug
>          Components: WSS4J Core
>    Affects Versions: 2.2.0
>         Environment: Using 2.2.0 in Apache CXF with WSS4JStaxOutInterceptor.
>            Reporter: J.Cranendonk
>            Assignee: Colm O hEigeartaigh
>             Fix For: 2.1.12, 2.2.1
>
>
> I am using WSS4j inside CXF, using the WSS4JStaxOutInterceptor, to generate a 
> XML Signature. This signature must include the KeyInfo (customer requires 
> Body and KeyInfo to be signed).
> My configuration includes:
> {noformat}
>         final Map< String, Object > outProps = new HashMap<>();
>         outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE);
>         // Crypto configuration left out
>         outProps.put(WSHandlerConstants.SIG_ALGO, 
> WSSConstants.NS_XMLDSIG_RSASHA256);
>         outProps.put(WSHandlerConstants.SIG_DIGEST_ALGO, 
> WSSConstants.NS_XENC_SHA256);
>         outProps.put(WSHandlerConstants.SIG_C14N_ALGO, 
> WSSConstants.NS_C14N_EXCL_OMIT_COMMENTS);
>         outProps.put(WSHandlerConstants.SIG_KEY_ID, "IssuerSerial");
>         
>         // Using defaults, same as: 
> "{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body;{Content}{http://www.w3.org/2000/09/xmldsig#}KeyInfo";
>         outProps.put(WSHandlerConstants.SIGNATURE_PARTS, "Body;{}{" + 
> WSSConstants.NS_DSIG + "}KeyInfo");      
>         jaxWsFactory.getOutInterceptors().add(new 
> WSS4JStaxOutInterceptor(outProps));
> {noformat}
> This results in an exception:
> {noformat}
> Caused by: org.apache.xml.security.exceptions.XMLSecurityException: Part to 
> sign not found: {http://www.w3.org/2000/09/xmldsig#}KeyInfo
>       at 
> org.apache.xml.security.stax.impl.processor.output.AbstractSignatureOutputProcessor.verifySignatureParts(AbstractSignatureOutputProcessor.java:155)
>       at 
> org.apache.xml.security.stax.impl.processor.output.AbstractSignatureOutputProcessor.doFinalInternal(AbstractSignatureOutputProcessor.java:86)
>       at 
> org.apache.wss4j.stax.impl.processor.output.WSSSignatureOutputProcessor.processEvent(WSSSignatureOutputProcessor.java:138)
>       at 
> org.apache.xml.security.stax.ext.AbstractOutputProcessor.processNextEvent(AbstractOutputProcessor.java:133)
>       at 
> org.apache.xml.security.stax.impl.OutputProcessorChainImpl.processEvent(OutputProcessorChainImpl.java:212)
>       at 
> org.apache.xml.security.stax.impl.XMLSecurityStreamWriter.chainProcessEvent(XMLSecurityStreamWriter.java:62)
>       ... 67 common frames omitted
> {noformat}
> If I change the SIGNATURE_PARTS to only "Body", things work as expected, and 
> a KeyInfo is included (but ofcourse not signed).
> I assume this is because of the order WSS4J does things, it first 
> creates/checks all the parts to be signed. And only after that creates the 
> KeyInfo structure.
> Debugging I can see that the following steps occur in this order:
> Checking the parts (and also creating the references or so, I think):
> {noformat}
> Thread [main] (Suspended (entry into method verifySignatureParts in 
> AbstractSignatureOutputProcessor))        
>       owns: PhaseInterceptorChain  (id=93)    
>       
> WSSSignatureOutputProcessor(AbstractSignatureOutputProcessor).verifySignatureParts(OutputProcessorChain)
>  line: 137      
>       
> WSSSignatureOutputProcessor(AbstractSignatureOutputProcessor).doFinalInternal(OutputProcessorChain)
>  line: 86    
>       WSSSignatureOutputProcessor.processEvent(XMLSecEvent, 
> OutputProcessorChain) line: 138   
>       
> WSSSignatureOutputProcessor(AbstractOutputProcessor).processNextEvent(XMLSecEvent,
>  OutputProcessorChain) line: 133      
>       OutputProcessorChainImpl.processEvent(XMLSecEvent) line: 212    
>       XMLSecurityStreamWriter.chainProcessEvent(XMLSecEvent) line: 62 
>       XMLSecurityStreamWriter.outputOpenStartElement() line: 83       
>       XMLSecurityStreamWriter.writeStartElement(String, String, String) line: 
> 116     
>       XMLStreamWriterOutput.beginStartTag(int, String) line: 103      
>       XMLStreamWriterOutput(XmlOutputAbstractImpl).beginStartTag(Name) line: 
> 87       
>       ForkXmlOutput.beginStartTag(Name) line: 65      
>       NamespaceContextImpl$Element.startElement(XmlOutput, Object) line: 481  
>       XMLSerializer.endNamespaceDecls(Object) line: 273       
>       XMLSerializer.childAsXsiType(Object, String, JaxBeanInfo, boolean) 
> line: 668    
>       SingleElementNodeProperty<BeanT,ValueT>.serializeBody(BeanT, 
> XMLSerializer, Object) line: 143   
>       ElementBeanInfoImpl$1.serializeBody(JAXBElement, XMLSerializer, Object) 
> line: 145       
>       ElementBeanInfoImpl$1.serializeBody(Object, XMLSerializer, Object) 
> line: 115    
>       ElementBeanInfoImpl.serializeBody(JAXBElement, XMLSerializer) line: 317 
>       ElementBeanInfoImpl.serializeRoot(JAXBElement, XMLSerializer) line: 324 
>       ElementBeanInfoImpl.serializeRoot(Object, XMLSerializer) line: 60       
>       XMLSerializer.childAsRoot(Object) line: 479     
>       MarshallerImpl.write(Object, XmlOutput, Runnable) line: 308     
>       MarshallerImpl.marshal(Object, XMLStreamWriter) line: 163       
>       JAXBEncoderDecoder.writeObject(Marshaller, Object, Object) line: 614    
>       JAXBEncoderDecoder.marshall(Marshaller, Object, MessagePartInfo, 
> Object) line: 243      
>       DataWriterImpl<T>.write(Object, MessagePartInfo, T) line: 232   
>       
> BareOutInterceptor(AbstractOutDatabindingInterceptor).writeParts(Message, 
> Exchange, BindingOperationInfo, MessageContentsList, List<MessagePartInfo>) 
> line: 137 
>       BareOutInterceptor.handleMessage(Message) line: 68      
>       PhaseInterceptorChain.doIntercept(Message) line: 308    
>       ClientImpl.doInvoke(ClientCallback, BindingOperationInfo, Object[], 
> Map<String,Object>, Exchange) line: 516     
> {noformat}
> Creating the KeyInfo structure:
> {noformat}
> Thread [main] (Suspended (entry into method 
> createKeyInfoStructureForSignature in WSSSignatureEndingOutputProcessor)) 
>       owns: PhaseInterceptorChain  (id=93)    
>       
> WSSSignatureEndingOutputProcessor.createKeyInfoStructureForSignature(OutputProcessorChain,
>  OutboundSecurityToken, boolean) line: 91     
>       
> WSSSignatureEndingOutputProcessor(AbstractSignatureEndingOutputProcessor).processHeaderEvent(OutputProcessorChain)
>  line: 216    
>       
> WSSSignatureEndingOutputProcessor.processHeaderEvent(OutputProcessorChain) 
> line: 77     
>       
> WSSSignatureEndingOutputProcessor(AbstractBufferingOutputProcessor).flushBufferAndCallbackAfterHeader(OutputProcessorChain,
>  Deque<XMLSecEvent>) line: 66        
>       
> WSSSignatureEndingOutputProcessor.flushBufferAndCallbackAfterHeader(OutputProcessorChain,
>  Deque<XMLSecEvent>) line: 284 
>       
> WSSSignatureEndingOutputProcessor(AbstractBufferingOutputProcessor).doFinal(OutputProcessorChain)
>  line: 52      
>       OutputProcessorChainImpl.doFinal() line: 220    
>       XMLSecurityStreamWriter.close() line: 190       
>       
> WSS4JStaxOutInterceptor$WSS4JStaxOutInterceptorInternal.handleMessageInternal(Message)
>  line: 336        
>       
> WSS4JStaxOutInterceptor$WSS4JStaxOutInterceptorInternal.handleMessage(Message)
>  line: 322        
>       PhaseInterceptorChain.doIntercept(Message) line: 308    
>       ClientImpl.doInvoke(ClientCallback, BindingOperationInfo, Object[], 
> Map<String,Object>, Exchange) line: 516     
> {noformat}
> I thought mayby this would be a limitation of the Stax way of working 
> (streaming over DOM), but in a quick test the DOM based wss4j implementation 
> also gives a similar exception, not being able to find the part to sign:
> {noformat}
> Caused by: org.apache.wss4j.common.ext.WSSecurityException: Element to 
> encrypt/sign not found: http://www.w3.org/2000/09/xmldsig#, KeyInfo
>       at 
> org.apache.wss4j.dom.message.WSSecSignatureBase.addReferencesToSign(WSSecSignatureBase.java:184)
>       ... 52 common frames omitted
> {noformat}
> Using OPTIONAL_SIGNATURE_PARTS instead of SIGNATURE_PARTS also doesn't solve 
> the issue, in that case the KeyInfo is simply not signed, again both for the 
> DOM as Stax version.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@ws.apache.org
For additional commands, e-mail: dev-h...@ws.apache.org

Reply via email to