1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.ws.security.message.token;
21
22 import java.io.IOException;
23 import java.util.Arrays;
24
25 import org.apache.ws.security.WSConstants;
26 import org.apache.ws.security.WSSecurityException;
27 import org.apache.ws.security.util.DOM2Writer;
28 import org.apache.ws.security.util.WSSecurityUtil;
29 import org.apache.ws.security.util.Base64;
30 import org.w3c.dom.Document;
31 import org.w3c.dom.Element;
32 import org.w3c.dom.Node;
33 import org.w3c.dom.Text;
34
35 import javax.security.auth.callback.CallbackHandler;
36 import javax.security.auth.callback.UnsupportedCallbackException;
37 import javax.xml.namespace.QName;
38
39
40
41
42
43
44
45 public class BinarySecurity {
46 public static final QName TOKEN_BST = new QName(WSConstants.WSSE_NS, "BinarySecurityToken");
47 public static final QName TOKEN_KI = new QName(WSConstants.WSSE_NS, "KeyIdentifier");
48 public static final String BASE64_ENCODING = WSConstants.SOAPMESSAGE_NS + "#Base64Binary";
49 private static final org.apache.commons.logging.Log LOG =
50 org.apache.commons.logging.LogFactory.getLog(BinarySecurity.class);
51 protected Element element = null;
52
53
54
55
56
57
58
59 public BinarySecurity(Element elem) throws WSSecurityException {
60 this(elem, true);
61 }
62
63
64
65
66
67
68
69 public BinarySecurity(Element elem, boolean bspCompliant) throws WSSecurityException {
70 element = elem;
71 QName el = new QName(element.getNamespaceURI(), element.getLocalName());
72 if (!(el.equals(TOKEN_BST) || el.equals(TOKEN_KI))) {
73 throw new WSSecurityException(
74 WSSecurityException.INVALID_SECURITY_TOKEN,
75 "unhandledToken",
76 new Object[] {el}
77 );
78 }
79 String encoding = getEncodingType();
80 if (bspCompliant && !BASE64_ENCODING.equals(encoding)) {
81
82 throw new WSSecurityException(
83 WSSecurityException.INVALID_SECURITY_TOKEN,
84 "badEncodingType",
85 new Object[] {encoding}
86 );
87 }
88
89 String valueType = getValueType();
90 if (bspCompliant && (valueType == null || "".equals(valueType))) {
91 throw new WSSecurityException(
92 WSSecurityException.INVALID_SECURITY_TOKEN,
93 "invalidValueType",
94 new Object[]{valueType}
95 );
96 }
97 }
98
99
100
101
102
103
104 public BinarySecurity(Document doc) {
105 element = doc.createElementNS(WSConstants.WSSE_NS, "wsse:BinarySecurityToken");
106 setEncodingType(BASE64_ENCODING);
107 element.appendChild(doc.createTextNode(""));
108 }
109
110
111
112
113
114
115 public BinarySecurity(CallbackHandler callbackHandler) throws WSSecurityException {
116 if (callbackHandler == null) {
117 LOG.debug("Trying to create a BinarySecurityToken via a null CallbackHandler");
118 throw new WSSecurityException(WSSecurityException.FAILURE);
119 }
120 TokenElementCallback[] callback = new TokenElementCallback[] { new TokenElementCallback() };
121
122 try {
123 callbackHandler.handle(callback);
124 } catch (IOException e) {
125 throw new IllegalStateException(
126 "IOException while creating a token element", e
127 );
128 } catch (UnsupportedCallbackException e) {
129 throw new IllegalStateException(
130 "UnsupportedCallbackException while creating a token element", e
131 );
132 }
133 element = callback[0].getTokenElement();
134 if (element == null) {
135 LOG.debug("CallbackHandler did not return a token element");
136 throw new WSSecurityException(WSSecurityException.FAILURE);
137 }
138 }
139
140
141
142
143
144 public void addWSSENamespace() {
145 WSSecurityUtil.setNamespace(element, WSConstants.WSSE_NS, WSConstants.WSSE_PREFIX);
146 }
147
148
149
150
151
152 public void addWSUNamespace() {
153 WSSecurityUtil.setNamespace(element, WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
154 }
155
156
157
158
159
160
161 public String getValueType() {
162 return element.getAttribute("ValueType");
163 }
164
165
166
167
168
169
170 public void setValueType(String type) {
171 element.setAttributeNS(null, "ValueType", type);
172 }
173
174
175
176
177
178
179 public String getEncodingType() {
180 return element.getAttribute("EncodingType");
181 }
182
183
184
185
186
187
188 public void setEncodingType(String encoding) {
189 element.setAttributeNS(null, "EncodingType", encoding);
190 }
191
192
193
194
195
196
197 public byte[] getToken() {
198 Node node = element.getFirstChild();
199 StringBuilder builder = new StringBuilder();
200 while (node != null) {
201 if (Node.TEXT_NODE == node.getNodeType()) {
202 builder.append(((Text)node).getData());
203 }
204 node = node.getNextSibling();
205 }
206
207 try {
208 return Base64.decode(builder.toString());
209 } catch (Exception ex) {
210 if (LOG.isDebugEnabled()) {
211 LOG.debug(ex.getMessage(), ex);
212 }
213 return null;
214 }
215 }
216
217
218
219
220
221
222 public void setToken(byte[] data) {
223 if (data == null) {
224 throw new IllegalArgumentException("data == null");
225 }
226 Text node = getFirstNode();
227 node.setData(Base64.encode(data));
228 }
229
230
231
232
233
234
235 protected Text getFirstNode() {
236 Node node = element.getFirstChild();
237 return (node != null && Node.TEXT_NODE == node.getNodeType()) ? (Text) node : null;
238 }
239
240
241
242
243
244
245 public Element getElement() {
246 return element;
247 }
248
249
250
251
252
253
254 public String getID() {
255 return element.getAttributeNS(WSConstants.WSU_NS, "Id");
256 }
257
258
259
260
261
262
263 public void setID(String id) {
264 element.setAttributeNS(WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":Id", id);
265 }
266
267
268
269
270
271
272 public String toString() {
273 return DOM2Writer.nodeToString((Node)element);
274 }
275
276 @Override
277 public int hashCode() {
278 int result = 17;
279 byte[] token = getToken();
280 if (token != null) {
281 result = 31 * result + Arrays.hashCode(token);
282 }
283 result = 31 * result + getValueType().hashCode();
284 result = 31 * result + getEncodingType().hashCode();
285
286 return result;
287 }
288
289 @Override
290 public boolean equals(Object object) {
291 if (!(object instanceof BinarySecurity)) {
292 return false;
293 }
294 BinarySecurity binarySecurity = (BinarySecurity)object;
295
296 byte[] token = binarySecurity.getToken();
297 if (!Arrays.equals(token, getToken())) {
298 return false;
299 }
300 String valueType = binarySecurity.getValueType();
301 if (!valueType.equals(getValueType())) {
302 return false;
303 }
304 String encodingType = binarySecurity.getEncodingType();
305 if (!encodingType.equals(getEncodingType())) {
306 return false;
307 }
308 return true;
309 }
310 }