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