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.validate;
21
22 import java.security.cert.X509Certificate;
23 import java.util.Collections;
24 import java.util.List;
25
26 import javax.security.auth.callback.CallbackHandler;
27
28 import org.apache.wss4j.common.bsp.BSPRule;
29 import org.apache.wss4j.common.crypto.Crypto;
30 import org.apache.wss4j.common.crypto.CryptoFactory;
31 import org.apache.wss4j.common.crypto.CryptoType;
32 import org.apache.wss4j.common.ext.WSSecurityException;
33 import org.apache.wss4j.common.saml.SAMLCallback;
34 import org.apache.wss4j.common.saml.SAMLUtil;
35 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
36 import org.apache.wss4j.common.token.BinarySecurity;
37 import org.apache.wss4j.common.token.X509Security;
38 import org.apache.wss4j.common.util.SOAPUtil;
39 import org.apache.wss4j.common.util.XMLUtils;
40 import org.apache.wss4j.dom.WSConstants;
41 import org.apache.wss4j.dom.common.SAML1CallbackHandler;
42
43 import org.apache.wss4j.dom.common.UsernamePasswordCallbackHandler;
44 import org.apache.wss4j.dom.engine.WSSConfig;
45 import org.apache.wss4j.dom.engine.WSSecurityEngine;
46 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
47 import org.apache.wss4j.dom.handler.RequestData;
48 import org.apache.wss4j.dom.handler.WSHandlerResult;
49 import org.apache.wss4j.dom.message.WSSecHeader;
50 import org.apache.wss4j.dom.message.WSSecSignature;
51 import org.apache.wss4j.dom.message.WSSecTimestamp;
52 import org.apache.wss4j.dom.message.WSSecUsernameToken;
53 import org.apache.wss4j.dom.util.WSSecurityUtil;
54
55 import org.junit.jupiter.api.Test;
56 import org.w3c.dom.Document;
57
58 import static org.junit.jupiter.api.Assertions.assertNotNull;
59 import static org.junit.jupiter.api.Assertions.assertTrue;
60 import static org.junit.jupiter.api.Assertions.fail;
61
62
63
64
65
66 public class ValidatorTest {
67 private static final org.slf4j.Logger LOG =
68 org.slf4j.LoggerFactory.getLogger(ValidatorTest.class);
69 private WSSecurityEngine secEngine = new WSSecurityEngine();
70
71
72
73
74 @Test
75 public void testExpiredTimestamp() throws Exception {
76
77 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
78 WSSecHeader secHeader = new WSSecHeader(doc);
79 secHeader.insertSecurityHeader();
80
81 WSSecTimestamp timestamp = new WSSecTimestamp(secHeader);
82 timestamp.setTimeToLive(-1);
83 Document createdDoc = timestamp.build();
84
85 if (LOG.isDebugEnabled()) {
86 String outputString =
87 XMLUtils.prettyDocumentToString(createdDoc);
88 LOG.debug(outputString);
89 }
90
91
92 WSSConfig wssConfig = WSSConfig.getNewInstance();
93 try {
94 verify(createdDoc, wssConfig, null, null);
95 fail("Expected failure on an expired timestamp");
96 } catch (WSSecurityException ex) {
97 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
98 }
99
100
101 wssConfig.setValidator(WSConstants.TIMESTAMP, NoOpValidator.class);
102 verify(createdDoc, wssConfig, null, null);
103 }
104
105
106
107
108 @Test
109 public void testUntrustedSignature() throws Exception {
110 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
111 WSSecHeader secHeader = new WSSecHeader(doc);
112 secHeader.insertSecurityHeader();
113
114 WSSecSignature sign = new WSSecSignature(secHeader);
115 sign.setUserInfo("wss40", "security");
116 sign.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER);
117
118 Crypto crypto = CryptoFactory.getInstance("wss40.properties");
119 Document signedDoc = sign.build(crypto);
120
121 if (LOG.isDebugEnabled()) {
122 String outputString =
123 XMLUtils.prettyDocumentToString(signedDoc);
124 LOG.debug(outputString);
125 }
126
127
128 Crypto cryptoCA = CryptoFactory.getInstance("crypto.properties");
129
130 WSSecurityEngine newEngine = new WSSecurityEngine();
131 RequestData data = new RequestData();
132 data.setSigVerCrypto(cryptoCA);
133 data.setIgnoredBSPRules(Collections.singletonList(BSPRule.R3063));
134 try {
135 newEngine.processSecurityHeader(signedDoc, data);
136 fail("Failure expected on issuer serial");
137 } catch (WSSecurityException ex) {
138 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
139 }
140
141
142 WSSConfig config = WSSConfig.getNewInstance();
143 config.setValidator(WSConstants.SIGNATURE, NoOpValidator.class);
144 newEngine.setWssConfig(config);
145 data.setWssConfig(config);
146 newEngine.processSecurityHeader(signedDoc, data);
147 }
148
149
150
151
152 @Test
153 public void testUsernameTokenBadText() throws Exception {
154 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
155 WSSecHeader secHeader = new WSSecHeader(doc);
156 secHeader.insertSecurityHeader();
157
158 WSSecUsernameToken builder = new WSSecUsernameToken(secHeader);
159 builder.setPasswordType(WSConstants.PASSWORD_TEXT);
160 builder.setUserInfo("wernerd", "verySecre");
161
162 Document signedDoc = builder.build();
163
164 if (LOG.isDebugEnabled()) {
165 String outputString =
166 XMLUtils.prettyDocumentToString(signedDoc);
167 LOG.debug(outputString);
168 }
169
170
171 WSSConfig wssConfig = WSSConfig.getNewInstance();
172 try {
173 verify(signedDoc, wssConfig, new UsernamePasswordCallbackHandler(), null);
174 fail("Failure expected on a bad password text");
175 } catch (WSSecurityException ex) {
176 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
177 }
178
179
180 wssConfig.setValidator(WSConstants.USERNAME_TOKEN, NoOpValidator.class);
181 verify(signedDoc, wssConfig, new UsernamePasswordCallbackHandler(), null);
182 }
183
184
185
186
187
188 @Test
189 public void testTransformedBST() throws Exception {
190 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
191
192 WSSecHeader secHeader = new WSSecHeader(doc);
193 secHeader.insertSecurityHeader();
194
195 X509Security bst = new X509Security(doc);
196 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
197 cryptoType.setAlias("wss40");
198 Crypto crypto = CryptoFactory.getInstance("wss40.properties");
199 X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
200 bst.setX509Certificate(certs[0]);
201
202 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), bst.getElement());
203
204 if (LOG.isDebugEnabled()) {
205 LOG.debug("BST output");
206 String outputString =
207 XMLUtils.prettyDocumentToString(doc);
208 LOG.debug(outputString);
209 }
210
211 WSSConfig config = WSSConfig.getNewInstance();
212 config.setValidator(WSConstants.BINARY_TOKEN, new BSTValidator());
213 WSSecurityEngine secEngine = new WSSecurityEngine();
214 secEngine.setWssConfig(config);
215 WSHandlerResult results =
216 secEngine.processSecurityHeader(doc, null, null, crypto);
217
218 List<WSSecurityEngineResult> bstResults =
219 results.getActionResults().get(WSConstants.BST);
220 WSSecurityEngineResult actionResult = bstResults.get(0);
221
222 BinarySecurity token =
223 (BinarySecurity)actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
224 assertNotNull(token);
225
226 SamlAssertionWrapper samlAssertion =
227 (SamlAssertionWrapper)actionResult.get(WSSecurityEngineResult.TAG_TRANSFORMED_TOKEN);
228 assertNotNull(samlAssertion);
229 }
230
231
232
233
234
235
236
237 @Test
238 public void testValidatedBSTSignature() throws Exception {
239 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
240 WSSecHeader secHeader = new WSSecHeader(doc);
241 secHeader.insertSecurityHeader();
242
243 WSSecSignature builder = new WSSecSignature(secHeader);
244 builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
245 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
246 Document signedDoc = builder.build(CryptoFactory.getInstance());
247
248 if (LOG.isDebugEnabled()) {
249 String outputString =
250 XMLUtils.prettyDocumentToString(signedDoc);
251 LOG.debug(outputString);
252 }
253
254 Crypto crypto = CryptoFactory.getInstance("wss40.properties");
255 WSSConfig config = WSSConfig.getNewInstance();
256 WSSecurityEngine secEngine = new WSSecurityEngine();
257 secEngine.setWssConfig(config);
258 try {
259 secEngine.processSecurityHeader(doc, null, null, crypto);
260 fail("Expected failure on untrusted signature");
261 } catch (WSSecurityException ex) {
262 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
263 }
264
265 config.setValidator(WSConstants.BINARY_TOKEN, new BSTValidator());
266 WSHandlerResult results =
267 secEngine.processSecurityHeader(doc, null, null, crypto);
268
269 List<WSSecurityEngineResult> bstResults =
270 results.getActionResults().get(WSConstants.BST);
271 WSSecurityEngineResult actionResult = bstResults.get(0);
272
273 BinarySecurity token =
274 (BinarySecurity)actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
275 assertNotNull(token);
276 }
277
278
279
280
281
282
283
284
285
286 private WSHandlerResult verify(
287 Document doc, WSSConfig wssConfig, CallbackHandler cb, Crypto crypto
288 ) throws Exception {
289 secEngine.setWssConfig(wssConfig);
290 return secEngine.processSecurityHeader(doc, null, cb, crypto);
291 }
292
293
294
295
296
297 private static class BSTValidator implements Validator {
298
299 public Credential validate(Credential credential, RequestData data) throws WSSecurityException {
300 BinarySecurity token = credential.getBinarySecurityToken();
301 if (token == null) {
302 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE);
303 }
304
305 try {
306 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
307 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
308 callbackHandler.setIssuer("www.example.com");
309
310 SAMLCallback samlCallback = new SAMLCallback();
311 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
312 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
313
314 credential.setTransformedToken(samlAssertion);
315 return credential;
316 } catch (Exception ex) {
317 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE);
318 }
319 }
320
321 }
322
323
324 }