J.Cranendonk created WSS-618: -------------------------------- Summary: 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
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