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.str;
21
22 import org.apache.ws.security.WSConstants;
23 import org.apache.ws.security.WSDocInfo;
24 import org.apache.ws.security.WSPasswordCallback;
25 import org.apache.ws.security.WSSConfig;
26 import org.apache.ws.security.WSSecurityEngine;
27 import org.apache.ws.security.WSSecurityEngineResult;
28 import org.apache.ws.security.WSSecurityException;
29 import org.apache.ws.security.handler.RequestData;
30 import org.apache.ws.security.message.token.BinarySecurity;
31 import org.apache.ws.security.message.token.DerivedKeyToken;
32 import org.apache.ws.security.message.token.Reference;
33 import org.apache.ws.security.message.token.SecurityTokenReference;
34 import org.apache.ws.security.message.token.UsernameToken;
35 import org.apache.ws.security.processor.Processor;
36 import org.apache.ws.security.saml.SAMLKeyInfo;
37 import org.apache.ws.security.saml.SAMLUtil;
38 import org.apache.ws.security.saml.ext.AssertionWrapper;
39 import org.apache.ws.security.util.WSSecurityUtil;
40 import org.w3c.dom.Element;
41
42 import java.security.Principal;
43 import java.security.PublicKey;
44 import java.security.cert.X509Certificate;
45 import java.util.Arrays;
46 import java.util.List;
47 import java.util.Map;
48
49 import javax.security.auth.callback.Callback;
50 import javax.xml.namespace.QName;
51
52
53
54
55
56 public class SecurityTokenRefSTRParser implements STRParser {
57
58
59
60
61 public static final String SIGNATURE_METHOD = "signature_method";
62
63 private byte[] secretKey;
64 private Principal principal;
65
66
67
68
69
70
71
72
73
74
75 public void parseSecurityTokenReference(
76 Element strElement,
77 RequestData data,
78 WSDocInfo wsDocInfo,
79 Map<String, Object> parameters
80 ) throws WSSecurityException {
81 boolean bspCompliant = true;
82 WSSConfig config = data.getWssConfig();
83 if (config != null) {
84 bspCompliant = config.isWsiBSPCompliant();
85 }
86
87 SecurityTokenReference secRef = new SecurityTokenReference(strElement, bspCompliant);
88
89 String uri = null;
90 if (secRef.containsReference()) {
91 uri = secRef.getReference().getURI();
92 if (uri.charAt(0) == '#') {
93 uri = uri.substring(1);
94 }
95 } else if (secRef.containsKeyIdentifier()) {
96 uri = secRef.getKeyIdentifierValue();
97 }
98
99 WSSecurityEngineResult result = wsDocInfo.getResult(uri);
100 if (result != null) {
101 processPreviousResult(result, secRef, data, parameters, wsDocInfo, bspCompliant);
102
103 if (secretKey == null) {
104 throw new WSSecurityException(
105 WSSecurityException.FAILED_CHECK, "unsupportedKeyId", new Object[] {uri}
106 );
107 }
108 } else if (secRef.containsReference()) {
109 Reference reference = secRef.getReference();
110
111 secretKey = getSecretKeyFromToken(uri, reference.getValueType(), data);
112 if (secretKey == null) {
113 Element token =
114 secRef.getTokenElement(strElement.getOwnerDocument(), wsDocInfo, data.getCallbackHandler());
115 QName el = new QName(token.getNamespaceURI(), token.getLocalName());
116 if (el.equals(WSSecurityEngine.BINARY_TOKEN)) {
117 Processor proc = data.getWssConfig().getProcessor(WSSecurityEngine.BINARY_TOKEN);
118 List<WSSecurityEngineResult> bstResult =
119 proc.handleToken(token, data, wsDocInfo);
120 BinarySecurity bstToken =
121 (BinarySecurity)bstResult.get(0).get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
122 if (bspCompliant) {
123 BSPEnforcer.checkBinarySecurityBSPCompliance(secRef, bstToken);
124 }
125 secretKey = (byte[])bstResult.get(0).get(WSSecurityEngineResult.TAG_SECRET);
126 }
127 }
128 if (secretKey == null) {
129 throw new WSSecurityException(
130 WSSecurityException.FAILED_CHECK, "unsupportedKeyId", new Object[] {uri}
131 );
132 }
133 } else if (secRef.containsKeyIdentifier()) {
134 String valueType = secRef.getKeyIdentifierValueType();
135 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(valueType)
136 || WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(valueType)) {
137 secretKey =
138 getSecretKeyFromToken(secRef.getKeyIdentifierValue(), valueType, data);
139 if (secretKey == null) {
140 AssertionWrapper assertion =
141 SAMLUtil.getAssertionFromKeyIdentifier(
142 secRef, strElement,
143 data, wsDocInfo
144 );
145 secretKey =
146 getSecretKeyFromAssertion(assertion, secRef, data, wsDocInfo, bspCompliant);
147 }
148 } else if (WSConstants.WSS_KRB_KI_VALUE_TYPE.equals(valueType)) {
149 secretKey =
150 getSecretKeyFromToken(secRef.getKeyIdentifierValue(), valueType, data);
151 if (secretKey == null) {
152 byte[] keyBytes = secRef.getSKIBytes();
153 List<WSSecurityEngineResult> resultsList =
154 wsDocInfo.getResultsByTag(WSConstants.BST);
155 for (WSSecurityEngineResult bstResult : resultsList) {
156 BinarySecurity bstToken =
157 (BinarySecurity)bstResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
158 byte[] tokenDigest = WSSecurityUtil.generateDigest(bstToken.getToken());
159 if (Arrays.equals(tokenDigest, keyBytes)) {
160 secretKey = (byte[])bstResult.get(WSSecurityEngineResult.TAG_SECRET);
161 break;
162 }
163 }
164 }
165 if (secretKey == null) {
166 throw new WSSecurityException(
167 WSSecurityException.FAILED_CHECK, "unsupportedKeyId", new Object[] {uri}
168 );
169 }
170 } else {
171 if (bspCompliant && SecurityTokenReference.ENC_KEY_SHA1_URI.equals(valueType)) {
172 BSPEnforcer.checkEncryptedKeyBSPCompliance(secRef);
173 }
174 secretKey =
175 getSecretKeyFromToken(
176 secRef.getKeyIdentifierValue(), secRef.getKeyIdentifierValueType(), data
177 );
178 if (secretKey == null) {
179 throw new WSSecurityException(
180 WSSecurityException.FAILED_CHECK, "unsupportedKeyId", new Object[] {uri}
181 );
182 }
183 }
184 } else {
185 throw new WSSecurityException(WSSecurityException.FAILED_CHECK, "noReference");
186 }
187 }
188
189
190
191
192
193 public X509Certificate[] getCertificates() {
194 return null;
195 }
196
197
198
199
200
201 public Principal getPrincipal() {
202 return principal;
203 }
204
205
206
207
208
209 public PublicKey getPublicKey() {
210 return null;
211 }
212
213
214
215
216
217 public byte[] getSecretKey() {
218 return secretKey;
219 }
220
221
222
223
224
225 public REFERENCE_TYPE getCertificatesReferenceType() {
226 return null;
227 }
228
229
230
231
232
233
234
235
236 public boolean isTrustedCredential() {
237 return false;
238 }
239
240
241
242
243
244
245
246
247
248 private byte[] getSecretKeyFromToken(
249 String id,
250 String type,
251 RequestData data
252 ) throws WSSecurityException {
253 if (id.charAt(0) == '#') {
254 id = id.substring(1);
255 }
256 WSPasswordCallback pwcb =
257 new WSPasswordCallback(id, null, type, WSPasswordCallback.SECRET_KEY, data);
258 try {
259 Callback[] callbacks = new Callback[]{pwcb};
260 if (data.getCallbackHandler() != null) {
261 data.getCallbackHandler().handle(callbacks);
262 return pwcb.getKey();
263 }
264 } catch (Exception e) {
265 throw new WSSecurityException(
266 WSSecurityException.FAILURE,
267 "noPassword",
268 new Object[] {id},
269 e
270 );
271 }
272
273 return null;
274 }
275
276
277
278
279 private byte[] getSecretKeyFromAssertion(
280 AssertionWrapper assertion,
281 SecurityTokenReference secRef,
282 RequestData data,
283 WSDocInfo wsDocInfo,
284 boolean bspCompliant
285 ) throws WSSecurityException {
286 if (bspCompliant) {
287 BSPEnforcer.checkSamlTokenBSPCompliance(secRef, assertion);
288 }
289 SAMLKeyInfo samlKi =
290 SAMLUtil.getCredentialFromSubject(assertion, data, wsDocInfo, bspCompliant);
291 if (samlKi == null) {
292 throw new WSSecurityException(
293 WSSecurityException.FAILED_CHECK, "invalidSAMLToken", new Object[] {"No Secret Key"}
294 );
295 }
296 return samlKi.getSecret();
297 }
298
299
300
301
302 private void processPreviousResult(
303 WSSecurityEngineResult result,
304 SecurityTokenReference secRef,
305 RequestData data,
306 Map<String, Object> parameters,
307 WSDocInfo wsDocInfo,
308 boolean bspCompliant
309 ) throws WSSecurityException {
310 int action = ((Integer)result.get(WSSecurityEngineResult.TAG_ACTION)).intValue();
311 if (WSConstants.ENCR == action) {
312 if (bspCompliant) {
313 BSPEnforcer.checkEncryptedKeyBSPCompliance(secRef);
314 }
315 secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
316 } else if (WSConstants.DKT == action) {
317 DerivedKeyToken dkt =
318 (DerivedKeyToken)result.get(WSSecurityEngineResult.TAG_DERIVED_KEY_TOKEN);
319 byte[] secret =
320 (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
321 String algorithm = (String)parameters.get(SIGNATURE_METHOD);
322 secretKey = dkt.deriveKey(WSSecurityUtil.getKeyLength(algorithm), secret);
323 principal = dkt.createPrincipal();
324 } else if (WSConstants.ST_UNSIGNED == action || WSConstants.ST_SIGNED == action) {
325 AssertionWrapper assertion =
326 (AssertionWrapper)result.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
327 secretKey =
328 getSecretKeyFromAssertion(assertion, secRef, data, wsDocInfo, bspCompliant);
329 } else if (WSConstants.SCT == action || WSConstants.BST == action) {
330 secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
331 } else if (WSConstants.UT_NOPASSWORD == action || WSConstants.UT == action) {
332 if (bspCompliant) {
333 BSPEnforcer.checkUsernameTokenBSPCompliance(secRef);
334 }
335 UsernameToken usernameToken =
336 (UsernameToken)result.get(WSSecurityEngineResult.TAG_USERNAME_TOKEN);
337
338 usernameToken.setRawPassword(data);
339 secretKey = usernameToken.getDerivedKey();
340 }
341 }
342
343
344 }