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;
21
22 import org.apache.ws.security.WSConstants;
23 import org.apache.ws.security.WSSConfig;
24 import org.apache.ws.security.WSSecurityException;
25 import org.apache.ws.security.conversation.ConversationConstants;
26 import org.apache.ws.security.conversation.ConversationException;
27 import org.apache.ws.security.conversation.dkalgo.AlgoFactory;
28 import org.apache.ws.security.conversation.dkalgo.DerivationAlgorithm;
29 import org.apache.ws.security.message.token.DerivedKeyToken;
30 import org.apache.ws.security.message.token.KerberosSecurity;
31 import org.apache.ws.security.message.token.Reference;
32 import org.apache.ws.security.message.token.SecurityTokenReference;
33 import org.apache.ws.security.util.Base64;
34 import org.apache.ws.security.util.WSSecurityUtil;
35 import org.w3c.dom.Document;
36 import org.w3c.dom.Element;
37
38 import java.io.UnsupportedEncodingException;
39
40
41
42
43
44
45
46
47 public abstract class WSSecDerivedKeyBase extends WSSecSignatureBase {
48
49 protected Document document;
50
51
52
53
54 protected byte[] ephemeralKey;
55
56
57
58
59 protected DerivedKeyToken dkt = null;
60
61
62
63
64 protected byte[] derivedKeyBytes = null;
65
66
67
68
69 protected String dktId = null;
70
71
72
73
74 protected String clientLabel = ConversationConstants.DEFAULT_LABEL;
75
76
77
78
79 protected String serviceLabel = ConversationConstants.DEFAULT_LABEL;
80
81
82
83
84 protected Element envelope = null;
85
86
87
88
89
90 protected String tokenIdentifier = null;
91
92
93
94
95
96 protected boolean tokenIdDirectId;
97
98
99
100
101
102
103
104 protected abstract int getDerivedKeyLength() throws WSSecurityException;
105
106
107
108
109 protected Element strElem;
110
111 private int wscVersion = ConversationConstants.DEFAULT_VERSION;
112
113 protected int derivedKeyLength = -1;
114
115 private String customValueType;
116
117
118 public WSSecDerivedKeyBase() {
119 super();
120 }
121 public WSSecDerivedKeyBase(WSSConfig config) {
122 super(config);
123 }
124
125
126
127
128
129 public void setExternalKey(byte[] ephemeralKey, String tokenIdentifier) {
130 this.ephemeralKey = ephemeralKey;
131 this.tokenIdentifier = tokenIdentifier;
132 }
133
134
135
136
137 public void setExternalKey(byte[] ephemeralKey, Element strElem) {
138 this.ephemeralKey = ephemeralKey;
139 this.strElem = strElem;
140 }
141
142
143
144
145 public String getTokenIdentifier() {
146 return tokenIdentifier;
147 }
148
149
150
151
152
153
154
155
156
157 public String getId() {
158 return dktId;
159 }
160
161
162
163
164
165 public void setClientLabel(String clientLabel) {
166 this.clientLabel = clientLabel;
167 }
168
169
170
171
172
173 public void setServiceLabel(String serviceLabel) {
174 this.serviceLabel = serviceLabel;
175 }
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191 public void prepare(Document doc) throws WSSecurityException, ConversationException {
192
193 document = doc;
194
195
196
197 int offset = 0;
198 int length = getDerivedKeyLength();
199 byte[] label;
200 try {
201 label = (clientLabel + serviceLabel).getBytes("UTF-8");
202 } catch (UnsupportedEncodingException e) {
203 throw new WSSecurityException("UTF-8 encoding is not supported", e);
204 }
205 byte[] nonce = WSSecurityUtil.generateNonce(16);
206
207 byte[] seed = new byte[label.length + nonce.length];
208 System.arraycopy(label, 0, seed, 0, label.length);
209 System.arraycopy(nonce, 0, seed, label.length, nonce.length);
210
211 DerivationAlgorithm algo =
212 AlgoFactory.getInstance(ConversationConstants.DerivationAlgorithm.P_SHA_1);
213
214 derivedKeyBytes = algo.createKey(ephemeralKey, seed, offset, length);
215
216
217 dkt = new DerivedKeyToken(wscVersion, document);
218 dktId = getWsConfig().getIdAllocator().createId("DK-", dkt);
219
220 dkt.setOffset(offset);
221 dkt.setLength(length);
222 dkt.setNonce(Base64.encode(nonce));
223 dkt.setID(dktId);
224
225 if (strElem == null) {
226 SecurityTokenReference secRef = new SecurityTokenReference(document);
227 String strUri = getWsConfig().getIdAllocator().createSecureId("STR-", secRef);
228 secRef.setID(strUri);
229
230 switch (keyIdentifierType) {
231 case WSConstants.CUSTOM_KEY_IDENTIFIER:
232 secRef.setKeyIdentifier(customValueType, tokenIdentifier);
233 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customValueType)) {
234 secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
235 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customValueType)) {
236 secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
237 } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customValueType)) {
238 secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
239 }
240 break;
241 default:
242 Reference ref = new Reference(document);
243
244 if (tokenIdDirectId) {
245 ref.setURI(tokenIdentifier);
246 } else {
247 ref.setURI("#" + tokenIdentifier);
248 }
249 if (customValueType != null && !"".equals(customValueType)) {
250 ref.setValueType(customValueType);
251 }
252 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customValueType)) {
253 secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
254 ref.setValueType(customValueType);
255 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customValueType)) {
256 secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
257 } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customValueType)) {
258 secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
259 ref.setValueType(customValueType);
260 } else if (KerberosSecurity.isKerberosToken(customValueType)) {
261 secRef.addTokenType(customValueType);
262 ref.setValueType(customValueType);
263 } else if (WSConstants.WSC_SCT.equals(customValueType)
264 || WSConstants.WSC_SCT_05_12.equals(customValueType)) {
265 ref.setValueType(customValueType);
266 } else if (!WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE.equals(customValueType)) {
267 secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
268 }
269
270 secRef.setReference(ref);
271 }
272
273 dkt.setSecurityTokenReference(secRef);
274 } else {
275 dkt.setSecurityTokenReference(strElem);
276 }
277 }
278
279
280
281
282
283
284
285
286
287
288
289
290 public void prependDKElementToHeader(WSSecHeader secHeader) {
291 WSSecurityUtil.prependChildElement(
292 secHeader.getSecurityHeader(), dkt.getElement()
293 );
294 }
295
296 public void appendDKElementToHeader(WSSecHeader secHeader) {
297 Element secHeaderElement = secHeader.getSecurityHeader();
298 secHeaderElement.appendChild(dkt.getElement());
299 }
300
301
302
303
304 public void setWscVersion(int wscVersion) {
305 this.wscVersion = wscVersion;
306 }
307
308 public Element getdktElement() {
309 return dkt.getElement();
310 }
311
312 public void setDerivedKeyLength(int keyLength) {
313 derivedKeyLength = keyLength;
314 }
315
316 public void setCustomValueType(String customValueType) {
317 this.customValueType = customValueType;
318 }
319
320 public void setTokenIdDirectId(boolean b) {
321 tokenIdDirectId = b;
322 }
323 }