DigestScheme can use an arbitrary digest algorithm requested by the target server (such SHA) as long as this algorithm is supported by the Java runtime
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@708595 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c3b6c426ca
commit
e434f1367a
|
@ -1,6 +1,11 @@
|
|||
Changes since 4.0 beta 1
|
||||
-------------------
|
||||
|
||||
* DigestScheme can use an arbitrary digest algorithm requested by the
|
||||
target server (such SHA) as long as this algorithm is supported by
|
||||
the Java runtime.
|
||||
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
||||
|
||||
* Fixed parsing and validation of RFC2109 compliant Set-Cookie headers
|
||||
by the Best-Match cookie spec.
|
||||
Contributed by Oleg Kalnichevski <olegk at apache.org>
|
||||
|
|
|
@ -288,7 +288,11 @@ public class DigestScheme extends RFC2617Scheme {
|
|||
"Unsupported qop in HTTP Digest authentication");
|
||||
}
|
||||
|
||||
MessageDigest md5Helper = createMessageDigest("MD5");
|
||||
String digAlg = algorithm;
|
||||
if (digAlg.equalsIgnoreCase("MD5-sess")) {
|
||||
digAlg = "MD5";
|
||||
}
|
||||
MessageDigest digester = createMessageDigest(digAlg);
|
||||
|
||||
String uname = credentials.getUserPrincipal().getName();
|
||||
String pwd = credentials.getPassword();
|
||||
|
@ -304,25 +308,25 @@ public class DigestScheme extends RFC2617Scheme {
|
|||
String a1 = tmp.toString();
|
||||
|
||||
//a1 is suitable for MD5 algorithm
|
||||
if(algorithm.equals("MD5-sess")) {
|
||||
if (algorithm.equalsIgnoreCase("MD5-sess")) {
|
||||
// H( unq(username-value) ":" unq(realm-value) ":" passwd )
|
||||
// ":" unq(nonce-value)
|
||||
// ":" unq(cnonce-value)
|
||||
|
||||
algorithm = "MD5";
|
||||
String cnonce = getCnonce();
|
||||
|
||||
String tmp2=encode(md5Helper.digest(EncodingUtils.getBytes(a1, charset)));
|
||||
StringBuilder tmp3 = new StringBuilder(tmp2.length() + nonce.length() + cnonce.length() + 2);
|
||||
String tmp2 = encode(digester.digest(EncodingUtils.getBytes(a1, charset)));
|
||||
StringBuilder tmp3 = new StringBuilder(
|
||||
tmp2.length() + nonce.length() + cnonce.length() + 2);
|
||||
tmp3.append(tmp2);
|
||||
tmp3.append(':');
|
||||
tmp3.append(nonce);
|
||||
tmp3.append(':');
|
||||
tmp3.append(cnonce);
|
||||
a1 = tmp3.toString();
|
||||
} else if (!algorithm.equals("MD5")) {
|
||||
throw new AuthenticationException("Unhandled algorithm " + algorithm + " requested");
|
||||
}
|
||||
String md5a1 = encode(md5Helper.digest(EncodingUtils.getBytes(a1, charset)));
|
||||
String hasha1 = encode(digester.digest(EncodingUtils.getBytes(a1, charset)));
|
||||
|
||||
String a2 = null;
|
||||
if (qopVariant == QOP_AUTH_INT) {
|
||||
|
@ -332,25 +336,26 @@ public class DigestScheme extends RFC2617Scheme {
|
|||
} else {
|
||||
a2 = method + ':' + uri;
|
||||
}
|
||||
String md5a2 = encode(md5Helper.digest(EncodingUtils.getAsciiBytes(a2)));
|
||||
String hasha2 = encode(digester.digest(EncodingUtils.getAsciiBytes(a2)));
|
||||
|
||||
// 3.2.2.1
|
||||
String serverDigestValue;
|
||||
if (qopVariant == QOP_MISSING) {
|
||||
StringBuilder tmp2 = new StringBuilder(md5a1.length() + nonce.length() + md5a2.length());
|
||||
tmp2.append(md5a1);
|
||||
StringBuilder tmp2 = new StringBuilder(
|
||||
hasha1.length() + nonce.length() + hasha1.length());
|
||||
tmp2.append(hasha1);
|
||||
tmp2.append(':');
|
||||
tmp2.append(nonce);
|
||||
tmp2.append(':');
|
||||
tmp2.append(md5a2);
|
||||
tmp2.append(hasha2);
|
||||
serverDigestValue = tmp2.toString();
|
||||
} else {
|
||||
String qopOption = getQopVariantString();
|
||||
String cnonce = getCnonce();
|
||||
|
||||
StringBuilder tmp2 = new StringBuilder(md5a1.length() + nonce.length()
|
||||
+ NC.length() + cnonce.length() + qopOption.length() + md5a2.length() + 5);
|
||||
tmp2.append(md5a1);
|
||||
StringBuilder tmp2 = new StringBuilder(hasha1.length() + nonce.length()
|
||||
+ NC.length() + cnonce.length() + qopOption.length() + hasha2.length() + 5);
|
||||
tmp2.append(hasha1);
|
||||
tmp2.append(':');
|
||||
tmp2.append(nonce);
|
||||
tmp2.append(':');
|
||||
|
@ -360,12 +365,12 @@ public class DigestScheme extends RFC2617Scheme {
|
|||
tmp2.append(':');
|
||||
tmp2.append(qopOption);
|
||||
tmp2.append(':');
|
||||
tmp2.append(md5a2);
|
||||
tmp2.append(hasha2);
|
||||
serverDigestValue = tmp2.toString();
|
||||
}
|
||||
|
||||
String serverDigest =
|
||||
encode(md5Helper.digest(EncodingUtils.getAsciiBytes(serverDigestValue)));
|
||||
encode(digester.digest(EncodingUtils.getAsciiBytes(serverDigestValue)));
|
||||
|
||||
return serverDigest;
|
||||
}
|
||||
|
@ -449,12 +454,9 @@ public class DigestScheme extends RFC2617Scheme {
|
|||
* @return encoded MD5, or <CODE>null</CODE> if encoding failed
|
||||
*/
|
||||
private static String encode(byte[] binaryData) {
|
||||
if (binaryData.length != 16) {
|
||||
return null;
|
||||
}
|
||||
|
||||
char[] buffer = new char[32];
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int n = binaryData.length;
|
||||
char[] buffer = new char[n * 2];
|
||||
for (int i = 0; i < n; i++) {
|
||||
int low = (binaryData[i] & 0x0f);
|
||||
int high = ((binaryData[i] & 0xf0) >> 4);
|
||||
buffer[i * 2] = HEXADECIMAL[high];
|
||||
|
|
|
@ -130,6 +130,25 @@ public class TestDigestScheme extends TestCase {
|
|||
assertEquals("e95a7ddf37c2eab009568b1ed134f89a", table.get("response"));
|
||||
}
|
||||
|
||||
public void testDigestAuthenticationWithSHA() throws Exception {
|
||||
String challenge = "Digest realm=\"realm1\", " +
|
||||
"nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " +
|
||||
"algorithm=SHA";
|
||||
Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
Credentials cred = new UsernamePasswordCredentials("username","password");
|
||||
AuthScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge);
|
||||
Header authResponse = authscheme.authenticate(cred, request);
|
||||
|
||||
Map<String, String> table = parseAuthResponse(authResponse);
|
||||
assertEquals("username", table.get("username"));
|
||||
assertEquals("realm1", table.get("realm"));
|
||||
assertEquals("/", table.get("uri"));
|
||||
assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce"));
|
||||
assertEquals("8769e82e4e28ecc040b969562b9050580c6d186d", table.get("response"));
|
||||
}
|
||||
|
||||
public void testDigestAuthenticationWithQueryStringInDigestURI() throws Exception {
|
||||
String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
|
||||
Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge);
|
||||
|
|
Loading…
Reference in New Issue