3

I'm in the throes of using wss4j to sign a SOAP document. I want mine to look like fig.1. However, it's coming out like fig.2. That is, fig.1 has a , which points to the document's BinarySecurityToken. Whereas fig.2 has a , which references the original certificate used to sign the doc.

A) Now, the BinarySecurityToken, is the binary value used on the provider's end, to locate the corresponding certificate chain in their keystore (used to validate the message).

B) I believe the SecurityTokenReference is used to reference the binary security token that contains the public key that should be used to verify the signature. So it looks like my challenge is making the pointer in fig.2 look like fig.1.

Is this correct? And if so, what's the switch in wss4j that can do that? The code that generates fig.2, is in fig.3 (Clojure code). So far, I've been digging around in wss4j source code for reference (ReferenceTest.java, SecurityTokenReferenceTest.java, SignatureTest.java).

        <wsse:SecurityTokenReference wsu:Id="STRId-A96305E32CE45DAB06139999212441542" 
                                     xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
           <wsse:Reference URI="#CertId-A96305E32CE45DAB06139999212441540"   <!-- this points to <wsse:BinarySecurityToken> -->
                                    ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/> 
        </wsse:SecurityTokenReference>

fig.1

        <wsse:SecurityTokenReference wsu:Id="STR-f9837b22-c073-45d2-92d0-2df67e823b2e"> 
          <ds:X509Data> 
            <ds:X509IssuerSerial> 
              <ds:X509IssuerName>CN=*.***.com,O=<org>,L=<city>,ST=<state>,C=<country>
              </ds:X509IssuerName> 
              <ds:X509SerialNumber><some-value> 
              </ds:X509SerialNumber> 
            </ds:X509IssuerSerial> 
          </ds:X509Data> 
        </wsse:SecurityTokenReference>

fig.2

  (defn sign-soap [soap-string]                                                                                                                                                                                                      

    (let [                                                                                                                                                                                                                           
          ;; ===> pull in keystore & cerificate                                                                                                                                                                                      
          ks (ks/keystore)                                                                                                                                                                                                           
          _ (ks/import-cert ks "server" (slurp "<mykeystore>"))                                                                                                                                                             

          cert (.getCertificate ks "server")                                                                                                                                                                                         
          keyEntry (.getEntry ks "server" nil)                                                                                                                                                                                       


          ;; ===> set Certificate on the signature object                                                                                                                                                                            
          builder (WSSecSignature.)                                                                                                                                                                                                  
          _ (.setX509Certificate builder cert)                                                                                                                                                                                       



          ;; ===> insert security header into the document                                                                                                                                                                           
          docu (soap/to-w3c-document soap-string)                                                                                                                                                                                    

          secHeader (WSSecHeader.)                                                                                                                                                                                                   
          _ (.insertSecurityHeader secHeader docu)                                                                                                                                                                                   


          ;; ===>                                                                                                                                                                                                                    
          crypto (CryptoFactory/getInstance)                                                                                                                                                                                         


          bst (X509Security. docu)                                                                                                                                                                                                   
          cryptoType (CryptoType. org.apache.wss4j.common.crypto.CryptoType$TYPE/ALIAS)                                                                                                                                              
          _ (.setAlias cryptoType "mykey")                                                                                                                                                                                           


          certs (.getX509Certificates crypto cryptoType)                                                                                                                                                                             
          _ (.setX509Certificate bst (first (seq certs)))                                                                                                                                                                            
          _ (WSSecurityUtil/prependChildElement                                                                                                                                                                                      
             (.getSecurityHeader secHeader)                                                                                                                                                                                          
             (.getElement bst))                                                                                                                                                                                                      

          ;; ===>                                                                                                                                                                                                                    
          timestamp (WSSecTimestamp.)                                                                                                                                                                                                
          _ (.setTimeToLive timestamp 300)                                                                                                                                                                                           

          createdDoc (.build timestamp docu secHeader)                                                                                                                                                                               


          ;; ===>                                                                                                                                                                                                                    
          encTimestamp (WSEncryptionPart. "Timestamp" WSConstants/WSU_NS "")                                                                                                                                                         
          encBody (WSEncryptionPart. "Body" "http://schemas.xmlsoap.org/soap/envelope/" "")                                                                                                                                          
          parts (ArrayList.)                                                                                                                                                                                                         
          _ (.add parts encTimestamp)                                                                                                                                                                                                
          _ (.add parts encBody)                                                                                                                                                                                                     
          _ (.setParts builder parts)                                                                                                                                                                                                

          _ (.setUserInfo builder "myusername" "mypassword")                                                                                                                                                                                

          signedDoc (.build builder createdDoc crypto secHeader)                                                                                                                                                                     

          secHeaderElement (.getSecurityHeader secHeader)                                                                                                                                                                            
          timestampNode (.. secHeaderElement (getElementsByTagNameNS WSConstants/WSU_NS "Timestamp") (item 0))                                                                                                                       
          _ (.setAttributeNS (cast Element timestampNode) WSConstants/XMLNS_NS "xmlns" WSConstants/WSU_NS)                                                                                                                           

          wss (XMLUtils/PrettyDocumentToString signedDoc)]                                                                                                                                                                           

      wss))

fig.3

Nutritioustim
  • 2,686
  • 4
  • 32
  • 57

2 Answers2

3

Ok, found the answer in an adjacent SO question WSS4j elements order during signing SOAP message.

So this user, while asking a different question, had a code example that did what I needed. Particularly the call to builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE). I love StackOverflow :)

builder.setX509Certificate(signingCert);
builder.setUserInfo(alias, new String(passphrase));
builder.setUseSingleCertificate(true);
builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
Community
  • 1
  • 1
Nutritioustim
  • 2,686
  • 4
  • 32
  • 57
1

Using any implementation of wss4j AbstractWSS4JInterceptor, the key identifier can be set to a direct reference by using either:

this.setProperty(WSHandlerConstants.ENC_KEY_ID, "DirectReference");
this.setProperty(WSHandlerConstants.SIG_KEY_ID, "DirectReference");