1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.ws.security.message.token;
19
20 import org.apache.ws.security.WSConstants;
21 import org.apache.ws.security.WSSConfig;
22 import org.apache.ws.security.WSSecurityException;
23 import org.apache.ws.security.util.DOM2Writer;
24 import org.apache.ws.security.util.WSSecurityUtil;
25 import org.apache.xml.security.utils.Base64;
26 import org.w3c.dom.Document;
27 import org.w3c.dom.Element;
28 import org.w3c.dom.Node;
29 import org.w3c.dom.Text;
30
31 import javax.xml.namespace.QName;
32
33 /***
34 * Binary Security Token.
35 * <p/>
36 *
37 * @author Davanum Srinivas (dims@yahoo.com).
38 */
39 public class BinarySecurity {
40 public static final String BASE64_BINARY = "Base64Binary";
41 private String base64Encoding;
42 protected Element element = null;
43 protected WSSConfig wssConfig = WSSConfig.getDefaultWSConfig();
44
45 public static String TOKEN = "BinarySecurityToken";
46 /***
47 * Constructor.
48 * <p/>
49 *
50 * @param elem
51 * @throws WSSecurityException
52 */
53 public BinarySecurity(WSSConfig wssConfig, Element elem) throws WSSecurityException {
54 this.element = elem;
55 this.wssConfig = wssConfig;
56 base64Encoding = getBase64EncodingValue(wssConfig);
57 boolean nsOK = false;
58 if (wssConfig.getProcessNonCompliantMessages()) {
59 for (int i = 0; i < WSConstants.WSSE_NS_ARRAY.length; ++i) {
60 if (WSConstants.WSSE_NS_ARRAY[i].equals(element.getNamespaceURI())) {
61 nsOK = true;
62 break;
63 }
64 }
65 } else if (wssConfig.getWsseNS().equals(element.getNamespaceURI())) {
66 nsOK = true;
67 }
68 if (!nsOK ||
69 !(element.getLocalName().equals(TOKEN) ||
70 element.getLocalName().equals("KeyIdentifier"))) {
71 QName el = new QName(this.element.getNamespaceURI(), this.element.getLocalName());
72 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN, "badTokenType", new Object[]{el});
73 }
74 if (!getEncodingType().endsWith(BASE64_BINARY)) {
75 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN, "badEncoding", new Object[]{getEncodingType()});
76 }
77 }
78
79 /***
80 * Constructor.
81 * <p/>
82 *
83 * @param doc
84 */
85 public BinarySecurity(WSSConfig wssConfig, Document doc) {
86 this.wssConfig = wssConfig;
87 base64Encoding = getBase64EncodingValue(wssConfig);
88 this.element = doc.createElementNS(wssConfig.getWsseNS(), "wsse:BinarySecurityToken");
89 WSSecurityUtil.setNamespace(this.element, wssConfig.getWsseNS(), WSConstants.WSSE_PREFIX);
90 setEncodingType(base64Encoding);
91 this.element.appendChild(doc.createTextNode(""));
92 }
93
94 /***
95 * get the value type.
96 * <p/>
97 *
98 * @return
99 */
100 public String getValueType() {
101 String valueType = this.element.getAttribute("ValueType");
102 if (valueType.length() == 0 &&
103 (wssConfig.getProcessNonCompliantMessages() || wssConfig.isBSTAttributesQualified())) {
104 valueType = WSSecurityUtil.getAttributeValueWSSE(element, "ValueType", null);
105 }
106 return valueType;
107 }
108
109 /***
110 * set the value type.
111 * <p/>
112 *
113 * @param type
114 */
115 protected void setValueType(String type) {
116 if (wssConfig.isBSTAttributesQualified()) {
117 this.element.setAttributeNS(wssConfig.getWsseNS(), WSConstants.WSSE_PREFIX + ":ValueType", type);
118 } else {
119 this.element.setAttributeNS(null, "ValueType", type);
120 }
121 }
122
123 /***
124 * get the encoding type.
125 * <p/>
126 *
127 * @return
128 */
129 public String getEncodingType() {
130 String encodingType = this.element.getAttribute("EncodingType");
131 if (encodingType.length() == 0 &&
132 (wssConfig.getProcessNonCompliantMessages() || wssConfig.isBSTAttributesQualified())) {
133 encodingType = WSSecurityUtil.getAttributeValueWSSE(element, "EncodingType", null);
134 }
135 return encodingType;
136 }
137
138 /***
139 * set the encoding type.
140 * <p/>
141 *
142 * @param encoding
143 */
144 protected void setEncodingType(String encoding) {
145 if (wssConfig.isBSTAttributesQualified()) {
146 this.element.setAttributeNS(wssConfig.getWsseNS(), WSConstants.WSSE_PREFIX + ":EncodingType", encoding);
147 } else {
148 this.element.setAttributeNS(null, "EncodingType", encoding);
149 }
150 }
151
152 /***
153 * get the byte array containing token information.
154 * <p/>
155 *
156 * @return
157 */
158 public byte[] getToken() {
159 Text node = getFirstNode();
160 if (node == null) {
161 return null;
162 }
163 try {
164 return Base64.decode(node.getData());
165 } catch (Exception e) {
166 return null;
167 }
168 }
169
170 /***
171 * set the token information.
172 * <p/>
173 *
174 * @param data
175 */
176 protected void setToken(byte[] data) {
177 if (data == null) {
178 throw new IllegalArgumentException("data == null");
179 }
180 Text node = getFirstNode();
181 node.setData(Base64.encode(data));
182 }
183
184 /***
185 * return the first text node.
186 * <p/>
187 *
188 * @return
189 */
190 protected Text getFirstNode() {
191 Node node = this.element.getFirstChild();
192 return ((node != null) && node instanceof Text) ? (Text) node : null;
193 }
194
195 /***
196 * return the dom element.
197 * <p/>
198 *
199 * @return
200 */
201 public Element getElement() {
202 return this.element;
203 }
204
205 /***
206 * get the id.
207 * <p/>
208 *
209 * @return
210 */
211 public String getID() {
212 return this.element.getAttributeNS(wssConfig.getWsuNS(), "Id");
213 }
214
215 /***
216 * set the id.
217 * <p/>
218 *
219 * @param id
220 */
221 public void setID(String id) {
222 String prefix = WSSecurityUtil.setNamespace(this.element, wssConfig.getWsuNS(), WSConstants.WSU_PREFIX);
223 this.element.setAttributeNS(wssConfig.getWsuNS(), prefix + ":Id", id);
224 }
225
226 /***
227 * return the string representation of the token.
228 * <p/>
229 *
230 * @return
231 */
232 public String toString() {
233 return DOM2Writer.nodeToString((Node) this.element);
234 }
235
236 public static String getBase64EncodingValue(WSSConfig wssConfig) {
237 if (wssConfig.isBSTValuesPrefixed()) {
238 return WSConstants.WSSE_PREFIX + ":" + BASE64_BINARY;
239 } else {
240 return WSConstants.SOAPMESSAGE_NS + "#" + BASE64_BINARY;
241 }
242 }
243 }