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.WSSecurityEngineResult;
27 import org.apache.ws.security.WSSecurityException;
28 import org.apache.ws.security.components.crypto.Crypto;
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.SecurityTokenReference;
32 import org.apache.ws.security.saml.SAMLKeyInfo;
33 import org.apache.ws.security.saml.SAMLUtil;
34 import org.apache.ws.security.saml.ext.AssertionWrapper;
35 import org.apache.ws.security.util.WSSecurityUtil;
36 import org.w3c.dom.Element;
37
38 import java.security.Principal;
39 import java.security.PublicKey;
40 import java.security.cert.X509Certificate;
41 import java.util.Arrays;
42 import java.util.List;
43 import java.util.Map;
44
45 import javax.security.auth.callback.Callback;
46
47
48
49
50
51 public class DerivedKeyTokenSTRParser implements STRParser {
52
53 private byte[] secretKey;
54
55
56
57
58
59
60
61
62
63
64 public void parseSecurityTokenReference(
65 Element strElement,
66 RequestData data,
67 WSDocInfo wsDocInfo,
68 Map<String, Object> parameters
69 ) throws WSSecurityException {
70 boolean bspCompliant = true;
71 Crypto crypto = data.getDecCrypto();
72 WSSConfig config = data.getWssConfig();
73
74 if (config != null) {
75 bspCompliant = config.isWsiBSPCompliant();
76 }
77
78 SecurityTokenReference secRef = new SecurityTokenReference(strElement, bspCompliant);
79
80 String uri = null;
81 if (secRef.containsReference()) {
82 uri = secRef.getReference().getURI();
83 if (uri.charAt(0) == '#') {
84 uri = uri.substring(1);
85 }
86 } else if (secRef.containsKeyIdentifier()) {
87 uri = secRef.getKeyIdentifierValue();
88 }
89
90 WSSecurityEngineResult result = wsDocInfo.getResult(uri);
91 if (result != null) {
92 processPreviousResult(result, secRef, data, wsDocInfo, bspCompliant);
93 } else if (secRef.containsReference()) {
94
95 secretKey =
96 getSecretKeyFromToken(uri, null, WSPasswordCallback.SECURITY_CONTEXT_TOKEN, data);
97 if (secretKey == null) {
98 throw new WSSecurityException(
99 WSSecurityException.FAILED_CHECK, "unsupportedKeyId", new Object[] {uri}
100 );
101 }
102 } else if (secRef.containsKeyIdentifier()) {
103 String keyIdentifierValueType = secRef.getKeyIdentifierValueType();
104 if (WSConstants.WSS_KRB_KI_VALUE_TYPE.equals(keyIdentifierValueType)) {
105 secretKey =
106 getSecretKeyFromToken(
107 secRef.getKeyIdentifierValue(), keyIdentifierValueType,
108 WSPasswordCallback.SECRET_KEY, data
109 );
110 if (secretKey == null) {
111 byte[] keyBytes = secRef.getSKIBytes();
112 List<WSSecurityEngineResult> resultsList =
113 wsDocInfo.getResultsByTag(WSConstants.BST);
114 for (WSSecurityEngineResult bstResult : resultsList) {
115 BinarySecurity bstToken =
116 (BinarySecurity)bstResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
117 byte[] tokenDigest = WSSecurityUtil.generateDigest(bstToken.getToken());
118 if (Arrays.equals(tokenDigest, keyBytes)) {
119 secretKey = (byte[])bstResult.get(WSSecurityEngineResult.TAG_SECRET);
120 break;
121 }
122 }
123 }
124 if (secretKey == null) {
125 throw new WSSecurityException(
126 WSSecurityException.FAILED_CHECK, "unsupportedKeyId", new Object[] {uri}
127 );
128 }
129 } else {
130 if (bspCompliant
131 && keyIdentifierValueType.equals(SecurityTokenReference.ENC_KEY_SHA1_URI)) {
132 BSPEnforcer.checkEncryptedKeyBSPCompliance(secRef);
133 }
134 X509Certificate[] certs = secRef.getKeyIdentifier(crypto);
135 if (certs == null || certs.length < 1 || certs[0] == null) {
136 secretKey =
137 this.getSecretKeyFromToken(
138 secRef.getKeyIdentifierValue(), keyIdentifierValueType,
139 WSPasswordCallback.SECRET_KEY, data
140 );
141 if (secretKey == null) {
142 throw new WSSecurityException(
143 WSSecurityException.FAILED_CHECK, "unsupportedKeyId", new Object[] {uri}
144 );
145 }
146 } else {
147 secretKey = crypto.getPrivateKey(certs[0], data.getCallbackHandler()).getEncoded();
148 }
149 }
150 } else {
151 throw new WSSecurityException(
152 WSSecurityException.FAILED_CHECK, "unsupportedKeyId"
153 );
154 }
155 }
156
157
158
159
160
161 public X509Certificate[] getCertificates() {
162 return null;
163 }
164
165
166
167
168
169 public Principal getPrincipal() {
170 return null;
171 }
172
173
174
175
176
177 public PublicKey getPublicKey() {
178 return null;
179 }
180
181
182
183
184
185 public byte[] getSecretKey() {
186 return secretKey;
187 }
188
189
190
191
192
193
194
195
196 public boolean isTrustedCredential() {
197 return false;
198 }
199
200
201
202
203
204 public REFERENCE_TYPE getCertificatesReferenceType() {
205 return null;
206 }
207
208
209
210
211
212
213
214
215
216 private byte[] getSecretKeyFromToken(
217 String id,
218 String type,
219 int identifier,
220 RequestData data
221 ) throws WSSecurityException {
222 if (id.charAt(0) == '#') {
223 id = id.substring(1);
224 }
225 WSPasswordCallback pwcb =
226 new WSPasswordCallback(id, null, type, identifier, data);
227 try {
228 Callback[] callbacks = new Callback[]{pwcb};
229 if (data.getCallbackHandler() != null) {
230 data.getCallbackHandler().handle(callbacks);
231 return pwcb.getKey();
232 }
233 } catch (Exception e) {
234 throw new WSSecurityException(
235 WSSecurityException.FAILURE,
236 "noPassword",
237 new Object[] {id},
238 e
239 );
240 }
241
242 return null;
243 }
244
245
246
247
248 private void processPreviousResult(
249 WSSecurityEngineResult result,
250 SecurityTokenReference secRef,
251 RequestData data,
252 WSDocInfo wsDocInfo,
253 boolean bspCompliant
254 ) throws WSSecurityException {
255 int action = ((Integer)result.get(WSSecurityEngineResult.TAG_ACTION)).intValue();
256 if (WSConstants.UT_NOPASSWORD == action || WSConstants.UT == action) {
257 if (bspCompliant) {
258 BSPEnforcer.checkUsernameTokenBSPCompliance(secRef);
259 }
260 secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
261 } else if (WSConstants.ENCR == action) {
262 if (bspCompliant) {
263 BSPEnforcer.checkEncryptedKeyBSPCompliance(secRef);
264 }
265 secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
266 } else if (WSConstants.SCT == action || WSConstants.BST == action) {
267 secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
268 } else if (WSConstants.ST_UNSIGNED == action || WSConstants.ST_SIGNED == action) {
269 AssertionWrapper assertion =
270 (AssertionWrapper)result.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
271 if (bspCompliant) {
272 BSPEnforcer.checkSamlTokenBSPCompliance(secRef, assertion);
273 }
274 SAMLKeyInfo keyInfo =
275 SAMLUtil.getCredentialFromSubject(assertion,
276 data, wsDocInfo, bspCompliant);
277
278
279 secretKey = keyInfo.getSecret();
280 } else {
281 throw new WSSecurityException(
282 WSSecurityException.FAILED_CHECK, "unsupportedKeyId"
283 );
284 }
285 }
286 }