diff --git a/src/main/java/com/ning/http/client/Realm.java b/src/main/java/com/ning/http/client/Realm.java index 8e68142c98..2d7899bbdb 100644 --- a/src/main/java/com/ning/http/client/Realm.java +++ b/src/main/java/com/ning/http/client/Realm.java @@ -526,12 +526,23 @@ private void newResponse() throws UnsupportedEncodingException { byte[] ha1 = md.digest(); md.reset(); + + //HA2 if qop is auth-int is methodName:url:md5(entityBody) md.update(new StringBuilder(methodName) .append(':') .append(uri).toString().getBytes("ISO-8859-1")); byte[] ha2 = md.digest(); - md.update(new StringBuilder(toBase16(ha1)) + if(qop==null || qop.equals("")) { + md.update(new StringBuilder(toBase16(ha1)) + .append(':') + .append(nonce) + .append(':') + .append(toBase16(ha2)).toString().getBytes("ISO-8859-1")); + + } else { + //qop ="auth" or "auth-int" + md.update(new StringBuilder(toBase16(ha1)) .append(':') .append(nonce) .append(':') @@ -542,6 +553,8 @@ private void newResponse() throws UnsupportedEncodingException { .append(qop) .append(':') .append(toBase16(ha2)).toString().getBytes("ISO-8859-1")); + } + byte[] digest = md.digest(); response = toHexString(digest); diff --git a/src/test/java/com/ning/http/client/RealmTest.java b/src/test/java/com/ning/http/client/RealmTest.java index f1aac2fcf9..6bd2a622b5 100644 --- a/src/test/java/com/ning/http/client/RealmTest.java +++ b/src/test/java/com/ning/http/client/RealmTest.java @@ -15,6 +15,9 @@ import com.ning.http.client.Realm.AuthScheme; import com.ning.http.client.Realm.RealmBuilder; import org.testng.Assert; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import org.testng.annotations.Test; public class RealmTest { @@ -36,4 +39,82 @@ public void testClone() { Assert.assertEquals( clone.getAlgorithm(), orig.getAlgorithm() ); Assert.assertEquals( clone.getAuthScheme(), orig.getAuthScheme() ); } + @Test(groups = "fast") + public void testOldDigestEmptyString() { + String qop=""; + testOldDigest(qop); + } + @Test(groups = "fast") + public void testOldDigestNull() { + String qop=null; + testOldDigest(qop); + } + + private void testOldDigest(String qop){ + String user="user"; + String pass="pass"; + String realm="realm"; + String nonce="nonce"; + String method="GET"; + String uri="/foo"; + RealmBuilder builder = new RealmBuilder(); + builder.setPrincipal( user ).setPassword( pass ); + builder.setNonce( nonce ); + builder.setUri( uri ); + builder.setMethodName(method); + builder.setRealmName( realm ); + builder.setQop(qop); + builder.setScheme( AuthScheme.DIGEST ); + Realm orig = builder.build(); + + String ha1=getMd5(user +":" + realm +":"+pass); + String ha2=getMd5(method +":"+ uri); + String expectedResponse=getMd5(ha1 +":" + nonce +":" + ha2); + + Assert.assertEquals(expectedResponse,orig.getResponse()); + } + + @Test(groups = "fast") + public void testStrongDigest() { + String user="user"; + String pass="pass"; + String realm="realm"; + String nonce="nonce"; + String method="GET"; + String uri="/foo"; + String qop="auth"; + RealmBuilder builder = new RealmBuilder(); + builder.setPrincipal( user ).setPassword( pass ); + builder.setNonce( nonce ); + builder.setUri( uri ); + builder.setMethodName(method); + builder.setRealmName( realm ); + builder.setQop(qop); + builder.setScheme( AuthScheme.DIGEST ); + Realm orig = builder.build(); + + String nc = orig.getNc(); + String cnonce = orig.getCnonce(); + String ha1=getMd5(user +":" + realm +":"+pass); + String ha2=getMd5(method +":"+ uri); + String expectedResponse=getMd5(ha1 +":" + nonce +":" + nc + ":" + cnonce +":" + qop + ":" + ha2); + + Assert.assertEquals(expectedResponse,orig.getResponse()); + } + + private String getMd5(String what){ + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(what.getBytes("ISO-8859-1")); + byte[] hash = md.digest(); + BigInteger bi = new BigInteger(1, hash); + String result = bi.toString(16); + if (result.length() % 2 != 0) { + return "0" + result; + } + return result; + } catch (Exception e) { + throw new RuntimeException(e); + } + } }