I am trying to generate a signature programmatically for the body of my SOAP Messages Looking at the spec it should be possible to have
<KeyInfo>
<X509Data>
<X509Certificate/>
<X509IssuerSerial>
<X509IssuerName>
...
</X509IssuerName>
<X509SerialNumber>...</X509SerialNumber>
</X509IssuerSerial>
</X509Data>
</KeyInfo>
I am using WSS4J 3.0.3
KeyPair keyPair = generateKeys();
Certificate certificate = generateCertificate(new KeyPair(getPublicKey(), getPrivateKey()));
String alias = "alias";
KeyStore keyStore = saveKeyStore(temporaryFolder.newFile(KEY_STORE_FILENAME), PASSWORD, certificate, keyPair, alias);
try(InputStream inputStream = TestSOAPSignatureValidationServiceWSSJ.class.getResourceAsStream("UnsignedDocument.xml")){
SOAPMessage message = MessageFactory.newInstance().createMessage(null, inputStream);
SOAPBody soapBody = message.getSOAPBody();
Document document = soapBody.getOwnerDocument();
WSSecHeader secHeader = new WSSecHeader(document);
secHeader.setMustUnderstand(true);
Element securityHeaderElement = document.createElementNS("http://schemas.xmlsoap.org/soap/security/2000-12", "SOAP-SEC:Signature");
message.getSOAPHeader().appendChild(securityHeaderElement);
secHeader.setSecurityHeaderElement(securityHeaderElement);
secHeader.insertSecurityHeader();
WSSecSignature signature = new WSSecSignature(secHeader);
signature.setX509Certificate((X509Certificate) certificate);
Properties properties = new Properties();
properties.setProperty("org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin");
Crypto crypto = CryptoFactory.getInstance(properties);
crypto.loadCertificate(new ByteArrayInputStream(certificate.getEncoded()));
((Merlin) crypto).setKeyStore(keyStore);
signature.setUserInfo(alias, PASSWORD);
WSDocInfo wsDocInfo = new WSDocInfo(document);
signature.setWsDocInfo(wsDocInfo);
signature.setAddInclusivePrefixes(false);
org.apache.xml.security.Init.init();
WSEncryptionPart wsEncryptionPart = new WSEncryptionPart(soapBody.getLocalName(), soapBody.getNamespaceURI(), "Content");
wsEncryptionPart.setElement(soapBody);
wsEncryptionPart.setId("Body");
signature.addReferencesToSign(List.of(wsEncryptionPart));
signature.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
Document signed = signature.build(crypto);
LOG.info(XMLUtils.prettyDocumentToString(signed));
}
}
but I am getting
<ds:KeyInfo Id="KI-c26f3a7c-ddf2-4889-9eef-55b541cb458f">
**<wsse:SecurityTokenReference** wsu:Id="STR-d5bbb99f-f861-4512-af56-f5e697c939ba" 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">
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>...</ds:X509IssuerName>
<ds:X509SerialNumber>..</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
**</wsse:SecurityTokenReference>**
</ds:KeyInfo>
Is it possible to instruct WSS4J to avoid the SecurityTokenReference tag and have the X509Data tag as a direct child of KeyInfo?
Thanks in advance!