-----Original Message-----
From: Robert Owen 
Sent: 17 January 2002 15:33
To: '[EMAIL PROTECTED]'
Subject: Digest authentication

Here are the beginnings of a digest authentication implementation for
HttpClient. It's a start as the client only supports the md5 algorithm and
does not use a generated client nonce or nonceCount (these are static), but
it does work against an Apache web server with digest authentication.[Rob]
I hope this helps as we would like to see support for digest authentication.

Cheers,
Rob.
 

--- HttpClient.java.orig        Thu Jan 17 15:02:22 2002
+++ HttpClient.java     Thu Jan 17 15:23:25 2002
@@ -972,7 +972,7 @@
         if (state.getAuthenticateToken() != null) {
 
             String challengeResponse = Authenticator.challengeResponse
-                (state, credentials);
+                (method, state, credentials);
             if (challengeResponse != null) {
                 if (debug > 1)
                     System.out.print("Authorization: "
--- Authenticator.java.orig     Thu Jan 17 15:19:11 2002
+++ Authenticator.java  Thu Jan 17 15:21:09 2002
@@ -90,7 +90,7 @@
      * @param credentials Credentials to use to answser the challenge
      * @return String response to the challenge
      */
-    public static String challengeResponse(State state,
+    public static String challengeResponse(HttpMethod method, State state,
                                            Credentials credentials)
         throws HttpException {
 
@@ -110,7 +110,7 @@
         if (challengeName.equalsIgnoreCase("basic")) {
             return basic(state, credentials);
         } else if (challengeName.equalsIgnoreCase("digest")) {
-            return digest(state, credentials);
+            return digest(method, state, credentials);
         } else {
 
         }
@@ -134,14 +134,94 @@
 
 
     /**
-     * Generate a basic response.
+     * Generate a digest response.
      *
      * @param credentials Credentials to use to answser the challenge
      */
-    public static String digest(State state, Credentials credentials) {
-
-        return null;
+    public static String digest(HttpMethod method, State state, Credentials 
+credentials) {
 
+               int p1, p2;
+               String realm      = "";
+               String nonce      = "";
+               String CNonce     = "0a4f113b";
+               String algorithm  = "";
+               String nonceCount = "00000001";
+               String qop        = "";
+               String domain     = "";
+               String opaque     = "";
+
+               String user       = credentials.getUserName();
+               String pw         = credentials.getPassword();
+               String methodName = method.getName();
+               String uri        = method.getPath();
+
+               String challenge = state.getAuthenticateToken();
+        if (challenge == null) return null;
+
+               java.security.MessageDigest md5;
+               try {
+                       md5 = java.security.MessageDigest.getInstance("MD5");
+               } catch (java.security.NoSuchAlgorithmException nsa) {
+                       return null;
+               }
+
+               // Assumes that none of the field values has a comma
+               java.util.StringTokenizer st = new java.util.StringTokenizer( 
+challenge.substring("digest ".length()), "," );
+               String aField, aFieldName, aFieldValue;
+               int equals;
+               while (st.hasMoreTokens())
+               {
+                       aField = st.nextToken();
+                       equals = aField.indexOf('=');
+                       if (equals < 0) continue;
+
+                       aFieldName = aField.substring(0,equals).trim();
+                       aFieldValue = aField.substring(equals+1);
+                       if (aFieldValue.indexOf('"') >= 0)
+                       {
+                               aFieldValue = aFieldValue.replace('"', ' ');
+                               aFieldValue = aFieldValue.trim();
+                       }
+
+                       if (aFieldName.equalsIgnoreCase("realm"))          realm     = 
+aFieldValue;
+                       else if (aFieldName.equalsIgnoreCase("domain"))    domain    = 
+aFieldValue;
+                       else if (aFieldName.equalsIgnoreCase("nonce"))     nonce     = 
+aFieldValue;
+                       else if (aFieldName.equalsIgnoreCase("algorithm")) algorithm = 
+aFieldValue;
+                       else if (aFieldName.equalsIgnoreCase("qop"))       qop       = 
+aFieldValue;
+                       else if (aFieldName.equalsIgnoreCase("opaque"))    opaque    = 
+aFieldValue;
+               }
+               if (!algorithm.equalsIgnoreCase("md5")) return null;
+
+               MD5Encoder md5enc = new MD5Encoder();
+               String A1 = user+":"+realm+":"+pw;
+               byte[] HA1 = md5.digest(A1.getBytes());
+               String HA1HEX = md5enc.encode(HA1);
+
+               String A2 = methodName+":"+uri;
+               byte[] HA2 = md5.digest(A2.getBytes());
+               String HA2HEX = md5enc.encode(HA2);
+
+               String request_digest_String = 
+HA1HEX+":"+nonce+":"+nonceCount+":"+CNonce+":"+qop+":"+HA2HEX;
+               byte[] request_digest_bytes = 
+md5.digest(request_digest_String.getBytes());
+               String request_digest = md5enc.encode(request_digest_bytes);
+
+               StringBuffer retStr = new StringBuffer("Digest 
+username=\""+user+"\",realm=\""+realm+
+                                   "\",nonce=\""+nonce+"\",uri=\""+uri+"\"");
+               if (!qop.equals(""))
+               {
+                       retStr.append(",qop=");
+                       retStr.append(qop);
+                       retStr.append(",nc=\"");
+                       retStr.append(nonceCount);
+                       retStr.append("\",cnonce=\"");
+                       retStr.append(CNonce);
+                       retStr.append("\"");
+               }
+               retStr.append(",response=\"");
+               retStr.append(request_digest);
+               retStr.append("\"");
+               if (!opaque.equals(""))retStr.append(",opaque=\""+opaque+"\"");
+               return retStr.toString();
     }
 
 

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to