You are viewing a plain text version of this content. The canonical link for it is here.
Posted to wss4j-dev@ws.apache.org by Mike <mc...@gmail.com> on 2009/02/11 13:12:29 UTC

WSS4J 1.5.5 UsernameToken handling

Hi again!

I have another issue when using WSS4J 1.5.5. I recently implemented
UsernameToken handling for our SOAP messages on WSS4J 1.5.4. This only
worked when I only signed the message, however when I added encryption to
the header the decryption would fail (when using 1.5.4) (as per first
message from me). Now however, after upgrading to 1.5.5, I get the following
exception when receiving a signed (no encryption) request:

> java.lang.NullPointerException
>  at
> org.apache.ws.security.processor.SignatureProcessor.verifyXMLSignature(SignatureProcessor.java:210)
>  at
> org.apache.ws.security.processor.SignatureProcessor.handleToken(SignatureProcessor.java:85)
>  at
> org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:326)
>  at
> org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:243)
>  at
> org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:196)

which points to (SignatureProcessor.java:210):

> ut = utProcessor.getUt();

on my system.

Am I doing something terribly wrong?

Versions:

Wss4j 1.5.5

xml-sec 1.4.2

BouncyCastle JDK15-141

Java 1.5.0_16

Axis 1.4 1855 April 22 2006

Metro 1.4

Thanks,

Mike

Sample UT signature Code:

>   Utils.trace(this.getClass(), "WSS Signing SOAP Envelope");
>
>   WSSecSignature sign = new WSSecSignature();
>   sign.setUserInfo(alias, pw);
>
>   WSSecUsernameToken secut = getUsernameToken(pMode, event, doc);
>
>   if (secut != null) {
>     sign.setUsernameToken(secut);
>     sign.setKeyIdentifierType (WSConstants.UT_SIGNING);
>     sign.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1);
>
>     Utils.debug(this.getClass(), "UsernameToken signing enabled from
> ProcessingMode '" + pMode.getID() + "' using Event '" + event.getID() +
> "'.");
>   } else {
>     sign.setSignatureAlgorithm(signAlgo);
>     sign.setSigCanonicalization(signCanonAlgo);
>   }
>
>   sign.setParts(getSignatureParts(pMode, event));
>
>   sign.prepare(doc, crypto, secHeader);
>
>   if (secut != null)
>     secut.prependToHeader(secHeader);
>
>   sign.prependToHeader(secHeader);
>
>   doc = sign.build(doc, crypto, secHeader);
>
>   Utils.trace(this.getClass(), "WSS Signed SOAP Envelope");

GetUsernameToken():

>   WSSecUsernameToken secut = null;
>
>   if (event != null) {
>     UsernameToken ut = event.getSecurity().getUsernameToken();
>
>     if (ut.getUsername().length() > 0 && ut.getPassword().length() > 0) {
>       Utils.trace(this.getClass(), "Found P-Mode '"+pMode.getID()+"'
> username and password");
>
>       secut = new WSSecUsernameToken();
>
>       if (ut.isDigest())
>         secut.setPasswordType(WSConstants.PASSWORD_DIGEST);
>       else
>         secut.setPasswordType(WSConstants.PASSWORD_TEXT);
>
>       secut.setUserInfo(ut.getUsername(), ut.getPassword());
>
>       if (ut.isCreated())
>         secut.addCreated();
>
>       if (ut.isNonce())
>         secut.addNonce();
>
>       secut.prepare(doc);
>     }
>   }

  return secut;
>

RE: WSS4J 1.5.5 UsernameToken handling

Posted by Colm O hEigeartaigh <co...@progress.com>.
Hi Mike,

 

The problem I think is that the UsernameToken should appear before the
signature in the security header. What's happening is that the
SignatureProcessor is trying to get the key to use to verify the
signature, but it can't find it as the Username Token hasn't been
processed yet. You have:

 

  if (secut != null)
    secut.prependToHeader(secHeader);
   
  sign.prependToHeader(secHeader);

 

Instead try:

 

sign.prependToHeader(secHeader);

 

  if (secut != null)
    secut.prependToHeader(secHeader);
   

BTW you're using the wrong secret key derivation algorithm in
UsernameToken. What you should be doing is something like (taken from a
unit test):

 

        WSSecUsernameToken builder = new WSSecUsernameToken();

        builder.setUserInfo("bob", "security");

        builder.addDerivedKey(true, null, 1000);

        builder.prepare(doc);

        

        WSSecSignature sign = new WSSecSignature();

        sign.setUsernameToken(builder);

        sign.setKeyIdentifierType(WSConstants.UT_SIGNING);

        sign.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1);

        Document signedDoc = sign.build(doc, null, secHeader); 

 

The "secret key" as opposed to "derived key" functionality is
non-standard, and in-secure (it sends the password in the UsernameToken
as well).

 

Colm.

 

________________________________

From: Mike [mailto:mcanix@gmail.com] 
Sent: 11 February 2009 12:12
To: wss4j-dev@ws.apache.org
Subject: WSS4J 1.5.5 UsernameToken handling

 

Hi again!

I have another issue when using WSS4J 1.5.5. I recently implemented
UsernameToken handling for our SOAP messages on WSS4J 1.5.4. This only
worked when I only signed the message, however when I added encryption
to the header the decryption would fail (when using 1.5.4) (as per first
message from me). Now however, after upgrading to 1.5.5, I get the
following exception when receiving a signed (no encryption) request:

	java.lang.NullPointerException
	 at
org.apache.ws.security.processor.SignatureProcessor.verifyXMLSignature(S
ignatureProcessor.java:210)
	 at
org.apache.ws.security.processor.SignatureProcessor.handleToken(Signatur
eProcessor.java:85)
	 at
org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurity
Engine.java:326)
	 at
org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurity
Engine.java:243)
	 at
org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurity
Engine.java:196)

which points to (SignatureProcessor.java:210):

	ut = utProcessor.getUt();

on my system.

Am I doing something terribly wrong?

Versions:

Wss4j 1.5.5

xml-sec 1.4.2

BouncyCastle JDK15-141

Java 1.5.0_16

Axis 1.4 1855 April 22 2006

Metro 1.4

Thanks,

Mike

Sample UT signature Code:

	  Utils.trace(this.getClass(), "WSS Signing SOAP Envelope");
	   
	  WSSecSignature sign = new WSSecSignature();
	  sign.setUserInfo(alias, pw);
	   
	  WSSecUsernameToken secut = getUsernameToken(pMode, event,
doc);
	
	  if (secut != null) {
	    sign.setUsernameToken(secut);
	    sign.setKeyIdentifierType (WSConstants.UT_SIGNING);
	
sign.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1);
	   
	    Utils.debug(this.getClass(), "UsernameToken signing enabled
from ProcessingMode '" + pMode.getID() + "' using Event '" +
event.getID() + "'.");
	  } else {
	    sign.setSignatureAlgorithm(signAlgo);
	    sign.setSigCanonicalization(signCanonAlgo);
	  }
	   
	  sign.setParts(getSignatureParts(pMode, event));
	
	  sign.prepare(doc, crypto, secHeader);
	   
	  if (secut != null)
	    secut.prependToHeader(secHeader);
	   
	  sign.prependToHeader(secHeader);
	   
	  doc = sign.build(doc, crypto, secHeader);
	   
	  Utils.trace(this.getClass(), "WSS Signed SOAP Envelope");

GetUsernameToken():

	  WSSecUsernameToken secut = null;
	   
	  if (event != null) {
	    UsernameToken ut = event.getSecurity().getUsernameToken();
	   
	    if (ut.getUsername().length() > 0 &&
ut.getPassword().length() > 0) {
	      Utils.trace(this.getClass(), "Found P-Mode
'"+pMode.getID()+"' username and password");
	   
	      secut = new WSSecUsernameToken();
	   
	      if (ut.isDigest())
	        secut.setPasswordType(WSConstants.PASSWORD_DIGEST);
	      else
	        secut.setPasswordType(WSConstants.PASSWORD_TEXT);
	   
	      secut.setUserInfo(ut.getUsername(), ut.getPassword());
	   
	      if (ut.isCreated())
	        secut.addCreated();
	   
	      if (ut.isNonce())
	        secut.addNonce();
	   
	      secut.prepare(doc);
	    }
	  }  

	  return secut;