1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.client.security;
15
16
17 import java.io.IOException;
18 import java.security.MessageDigest;
19 import java.util.Map;
20
21 import org.eclipse.jetty.client.HttpExchange;
22 import org.eclipse.jetty.http.HttpHeaders;
23 import org.eclipse.jetty.util.StringUtil;
24 import org.eclipse.jetty.util.TypeUtil;
25
26 public class DigestAuthentication implements Authentication
27 {
28 private static final String NC = "00000001";
29 Realm securityRealm;
30 Map details;
31
32 public DigestAuthentication(Realm realm, Map details)
33 {
34 this.securityRealm=realm;
35 this.details=details;
36 }
37
38
39 public void setCredentials( HttpExchange exchange )
40 throws IOException
41 {
42 StringBuilder buffer = new StringBuilder().append("Digest");
43
44 buffer.append(" ").append("username").append('=').append('"').append(securityRealm.getPrincipal()).append('"');
45
46 buffer.append(", ").append("realm").append('=').append('"').append(String.valueOf(details.get("realm"))).append('"');
47
48 buffer.append(", ").append("nonce").append('=').append('"').append(String.valueOf(details.get("nonce"))).append('"');
49
50 buffer.append(", ").append("uri").append('=').append('"').append(exchange.getURI()).append('"');
51
52 buffer.append(", ").append("algorithm").append('=').append(String.valueOf(details.get("algorithm")));
53
54 String cnonce = newCnonce(exchange, securityRealm, details);
55
56 buffer.append(", ").append("response").append('=').append('"').append(newResponse(cnonce,
57 exchange, securityRealm, details)).append('"');
58
59 buffer.append(", ").append("qop").append('=').append(String.valueOf(details.get("qop")));
60
61
62 buffer.append(", ").append("nc").append('=').append(NC);
63
64 buffer.append(", ").append("cnonce").append('=').append('"').append(cnonce).append('"');
65
66 exchange.setRequestHeader( HttpHeaders.AUTHORIZATION,
67 new String(buffer.toString().getBytes(StringUtil.__ISO_8859_1)));
68 }
69
70 protected String newResponse(String cnonce, HttpExchange exchange, Realm securityRealm, Map details)
71 {
72 try{
73 MessageDigest md = MessageDigest.getInstance("MD5");
74
75
76 md.update(securityRealm.getPrincipal().getBytes(StringUtil.__ISO_8859_1));
77 md.update((byte)':');
78 md.update(String.valueOf(details.get("realm")).getBytes(StringUtil.__ISO_8859_1));
79 md.update((byte)':');
80 md.update(securityRealm.getCredentials().getBytes(StringUtil.__ISO_8859_1));
81 byte[] ha1 = md.digest();
82
83 md.reset();
84 md.update(exchange.getMethod().getBytes(StringUtil.__ISO_8859_1));
85 md.update((byte)':');
86 md.update(exchange.getURI().getBytes(StringUtil.__ISO_8859_1));
87 byte[] ha2=md.digest();
88
89 md.update(TypeUtil.toString(ha1,16).getBytes(StringUtil.__ISO_8859_1));
90 md.update((byte)':');
91 md.update(String.valueOf(details.get("nonce")).getBytes(StringUtil.__ISO_8859_1));
92 md.update((byte)':');
93 md.update(NC.getBytes(StringUtil.__ISO_8859_1));
94 md.update((byte)':');
95 md.update(cnonce.getBytes(StringUtil.__ISO_8859_1));
96 md.update((byte)':');
97 md.update(String.valueOf(details.get("qop")).getBytes(StringUtil.__ISO_8859_1));
98 md.update((byte)':');
99 md.update(TypeUtil.toString(ha2,16).getBytes(StringUtil.__ISO_8859_1));
100 byte[] digest=md.digest();
101
102
103 return encode(digest);
104 }
105 catch(Exception e)
106 {
107 e.printStackTrace();
108 return null;
109 }
110 }
111
112 protected String newCnonce(HttpExchange exchange, Realm securityRealm, Map details)
113 {
114 try
115 {
116 MessageDigest md = MessageDigest.getInstance("MD5");
117 byte[] b= md.digest(String.valueOf(System.currentTimeMillis()).getBytes(StringUtil.__ISO_8859_1));
118 return encode(b);
119 }
120 catch(Exception e)
121 {
122 e.printStackTrace();
123 return null;
124 }
125 }
126
127 private static String encode(byte[] data)
128 {
129 StringBuilder buffer = new StringBuilder();
130 for (int i=0; i<data.length; i++)
131 {
132 buffer.append(Integer.toHexString((data[i] & 0xf0) >>> 4));
133 buffer.append(Integer.toHexString(data[i] & 0x0f));
134 }
135 return buffer.toString();
136 }
137
138 }