1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.dom.str;
21
22 import java.util.Arrays;
23 import java.util.List;
24
25 import javax.xml.namespace.QName;
26
27 import org.apache.wss4j.common.ext.WSPasswordCallback;
28 import org.apache.wss4j.common.ext.WSSecurityException;
29 import org.apache.wss4j.common.saml.SAMLKeyInfo;
30 import org.apache.wss4j.common.saml.SAMLUtil;
31 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
32 import org.apache.wss4j.common.token.BinarySecurity;
33 import org.apache.wss4j.common.token.Reference;
34 import org.apache.wss4j.common.token.SecurityTokenReference;
35 import org.apache.wss4j.common.util.KeyUtils;
36 import org.apache.wss4j.common.util.UsernameTokenUtil;
37 import org.apache.wss4j.common.util.XMLUtils;
38 import org.apache.wss4j.dom.WSConstants;
39 import org.apache.wss4j.dom.WSDocInfo;
40 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
41 import org.apache.wss4j.dom.handler.RequestData;
42 import org.apache.wss4j.dom.message.token.DerivedKeyToken;
43 import org.apache.wss4j.dom.message.token.UsernameToken;
44 import org.apache.wss4j.dom.processor.Processor;
45 import org.apache.wss4j.dom.saml.WSSSAMLKeyInfoProcessor;
46 import org.w3c.dom.Element;
47
48
49
50
51
52 public class SecurityTokenRefSTRParser implements STRParser {
53
54
55
56
57
58
59
60
61 public STRParserResult parseSecurityTokenReference(STRParserParameters parameters) throws WSSecurityException {
62
63 if (parameters == null || parameters.getData() == null || parameters.getData().getWsDocInfo() == null
64 || parameters.getStrElement() == null) {
65 throw new WSSecurityException(
66 WSSecurityException.ErrorCode.FAILURE, "invalidSTRParserParameter"
67 );
68 }
69
70 SecurityTokenReference secRef =
71 new SecurityTokenReference(parameters.getStrElement(), parameters.getData().getBSPEnforcer());
72
73 String uri = null;
74 if (secRef.getReference() != null) {
75 uri = secRef.getReference().getURI();
76 uri = XMLUtils.getIDFromReference(uri);
77 } else if (secRef.containsKeyIdentifier()) {
78 uri = secRef.getKeyIdentifierValue();
79 }
80
81 WSSecurityEngineResult result = parameters.getData().getWsDocInfo().getResult(uri);
82 if (result != null) {
83 return processPreviousResult(result, secRef, uri, parameters);
84 }
85
86 return processSTR(secRef, uri, parameters);
87 }
88
89
90
91
92 private byte[] getSecretKeyFromAssertion(
93 SamlAssertionWrapper samlAssertion,
94 SecurityTokenReference secRef,
95 RequestData data
96 ) throws WSSecurityException {
97 STRParserUtil.checkSamlTokenBSPCompliance(secRef, samlAssertion, data.getBSPEnforcer());
98 SAMLKeyInfo samlKi =
99 SAMLUtil.getCredentialFromSubject(samlAssertion, new WSSSAMLKeyInfoProcessor(data), data.getSigVerCrypto());
100 if (samlKi == null) {
101 throw new WSSecurityException(
102 WSSecurityException.ErrorCode.FAILED_CHECK, "invalidSAMLToken",
103 new Object[] {"No Secret Key"});
104 }
105 return samlKi.getSecret();
106 }
107
108
109
110
111 private STRParserResult processPreviousResult(
112 WSSecurityEngineResult result,
113 SecurityTokenReference secRef,
114 String uri,
115 STRParserParameters parameters
116 ) throws WSSecurityException {
117 STRParserResult parserResult = new STRParserResult();
118 RequestData data = parameters.getData();
119
120 Integer action = (Integer) result.get(WSSecurityEngineResult.TAG_ACTION);
121 if (action != null && WSConstants.ENCR == action.intValue()) {
122 STRParserUtil.checkEncryptedKeyBSPCompliance(secRef, data.getBSPEnforcer());
123 byte[] secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
124 parserResult.setSecretKey(secretKey);
125 } else if (action != null && WSConstants.DKT == action.intValue()) {
126 DerivedKeyToken dkt =
127 (DerivedKeyToken)result.get(WSSecurityEngineResult.TAG_DERIVED_KEY_TOKEN);
128 int keyLength = dkt.getLength();
129 if (keyLength <= 0 && parameters.getDerivationKeyLength() > 0) {
130 keyLength = parameters.getDerivationKeyLength();
131 }
132 byte[] secret = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
133 parserResult.setSecretKey(dkt.deriveKey(keyLength, secret));
134 parserResult.setPrincipal(dkt.createPrincipal());
135 } else if (action != null
136 && (WSConstants.ST_UNSIGNED == action.intValue() || WSConstants.ST_SIGNED == action.intValue())) {
137 SamlAssertionWrapper samlAssertion =
138 (SamlAssertionWrapper)result.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
139 byte[] secretKey =
140 getSecretKeyFromAssertion(samlAssertion, secRef, data);
141 parserResult.setSecretKey(secretKey);
142 } else if (action != null
143 && (WSConstants.SCT == action.intValue() || WSConstants.BST == action.intValue())) {
144 byte[] secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
145 parserResult.setSecretKey(secretKey);
146 } else if (action != null
147 && (WSConstants.UT_NOPASSWORD == action.intValue() || WSConstants.UT == action.intValue())) {
148 STRParserUtil.checkUsernameTokenBSPCompliance(secRef, data.getBSPEnforcer());
149 UsernameToken usernameToken =
150 (UsernameToken)result.get(WSSecurityEngineResult.TAG_USERNAME_TOKEN);
151
152 String rawPassword =
153 UsernameTokenUtil.getRawPassword(data.getCallbackHandler(), usernameToken.getName(),
154 usernameToken.getPassword(), usernameToken.getPasswordType());
155 byte[] secretKey = usernameToken.getDerivedKey(data.getBSPEnforcer(), rawPassword);
156 parserResult.setSecretKey(secretKey);
157 }
158
159 if (parserResult.getSecretKey() == null) {
160 throw new WSSecurityException(
161 WSSecurityException.ErrorCode.FAILED_CHECK, "unsupportedKeyId",
162 new Object[] {uri});
163 }
164
165 return parserResult;
166 }
167
168 private STRParserResult processSTR(
169 SecurityTokenReference secRef,
170 String uri,
171 STRParserParameters parameters
172 ) throws WSSecurityException {
173 STRParserResult parserResult = new STRParserResult();
174 RequestData data = parameters.getData();
175 Element strElement = parameters.getStrElement();
176 WSDocInfo wsDocInfo = data.getWsDocInfo();
177
178 if (secRef.containsReference()) {
179 Reference reference = secRef.getReference();
180
181 byte[] secretKey =
182 STRParserUtil.getSecretKeyFromToken(uri, reference.getValueType(),
183 WSPasswordCallback.SECRET_KEY, data);
184 if (secretKey == null || secretKey.length == 0) {
185 Element token =
186 STRParserUtil.getTokenElement(strElement.getOwnerDocument(), wsDocInfo, data.getCallbackHandler(),
187 uri, reference.getValueType());
188 QName el = new QName(token.getNamespaceURI(), token.getLocalName());
189 if (el.equals(WSConstants.BINARY_TOKEN)) {
190 Processor proc = data.getWssConfig().getProcessor(WSConstants.BINARY_TOKEN);
191 List<WSSecurityEngineResult> bstResult = proc.handleToken(token, data);
192 BinarySecurity bstToken =
193 (BinarySecurity)bstResult.get(0).get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
194 STRParserUtil.checkBinarySecurityBSPCompliance(secRef, bstToken, data.getBSPEnforcer());
195 secretKey = (byte[])bstResult.get(0).get(WSSecurityEngineResult.TAG_SECRET);
196 }
197 }
198 if (secretKey == null) {
199 throw new WSSecurityException(
200 WSSecurityException.ErrorCode.FAILED_CHECK, "unsupportedKeyId",
201 new Object[] {uri});
202 }
203 parserResult.setSecretKey(secretKey);
204 } else if (secRef.containsKeyIdentifier()) {
205 String valueType = secRef.getKeyIdentifierValueType();
206 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(valueType)
207 || WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(valueType)) {
208 byte[] secretKey =
209 STRParserUtil.getSecretKeyFromToken(secRef.getKeyIdentifierValue(), valueType,
210 WSPasswordCallback.SECRET_KEY, data);
211 if (secretKey == null || secretKey.length == 0) {
212 SamlAssertionWrapper samlAssertion =
213 STRParserUtil.getAssertionFromKeyIdentifier(
214 secRef, strElement, data
215 );
216 secretKey = getSecretKeyFromAssertion(samlAssertion, secRef, data);
217 }
218 parserResult.setSecretKey(secretKey);
219 } else if (WSConstants.WSS_KRB_KI_VALUE_TYPE.equals(valueType)) {
220 byte[] secretKey =
221 STRParserUtil.getSecretKeyFromToken(secRef.getKeyIdentifierValue(), valueType,
222 WSPasswordCallback.SECRET_KEY, data);
223 if (secretKey == null || secretKey.length == 0) {
224 byte[] keyBytes = secRef.getSKIBytes();
225 List<WSSecurityEngineResult> resultsList =
226 wsDocInfo.getResultsByTag(WSConstants.BST);
227 for (WSSecurityEngineResult bstResult : resultsList) {
228 BinarySecurity bstToken =
229 (BinarySecurity)bstResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
230 byte[] tokenDigest = KeyUtils.generateDigest(bstToken.getToken());
231 if (Arrays.equals(tokenDigest, keyBytes)) {
232 secretKey = (byte[])bstResult.get(WSSecurityEngineResult.TAG_SECRET);
233 break;
234 }
235 }
236 }
237 if (secretKey == null) {
238 throw new WSSecurityException(
239 WSSecurityException.ErrorCode.FAILED_CHECK, "unsupportedKeyId",
240 new Object[] {uri});
241 }
242 parserResult.setSecretKey(secretKey);
243 } else {
244 if (SecurityTokenReference.ENC_KEY_SHA1_URI.equals(valueType)) {
245 STRParserUtil.checkEncryptedKeyBSPCompliance(secRef, data.getBSPEnforcer());
246 }
247 byte[] secretKey =
248 STRParserUtil.getSecretKeyFromToken(
249 secRef.getKeyIdentifierValue(), secRef.getKeyIdentifierValueType(),
250 WSPasswordCallback.SECRET_KEY, data
251 );
252 if (secretKey == null || secretKey.length == 0) {
253 throw new WSSecurityException(
254 WSSecurityException.ErrorCode.FAILED_CHECK, "unsupportedKeyId",
255 new Object[] {uri});
256 }
257 parserResult.setSecretKey(secretKey);
258 }
259 } else {
260 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, "noReference");
261 }
262
263 return parserResult;
264 }
265
266 }