How to omit SecurityTokenReference from KeyInfo using wss4j?

25 Views Asked by At

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!

0

There are 0 best solutions below