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.misc;
21
22 import java.io.IOException;
23
24 import javax.crypto.KeyGenerator;
25 import javax.crypto.SecretKey;
26 import javax.security.auth.callback.Callback;
27 import javax.security.auth.callback.CallbackHandler;
28 import javax.security.auth.callback.UnsupportedCallbackException;
29 import javax.xml.namespace.QName;
30
31 import org.apache.wss4j.common.bsp.BSPEnforcer;
32 import org.apache.wss4j.common.crypto.Crypto;
33 import org.apache.wss4j.common.crypto.CryptoFactory;
34 import org.apache.wss4j.common.ext.WSPasswordCallback;
35 import org.apache.wss4j.common.ext.WSSecurityException;
36 import org.apache.wss4j.common.token.Reference;
37 import org.apache.wss4j.common.util.KeyUtils;
38 import org.apache.wss4j.common.util.SOAPUtil;
39 import org.apache.wss4j.dom.WSConstants;
40
41 import org.apache.wss4j.dom.engine.WSSConfig;
42 import org.apache.wss4j.dom.engine.WSSecurityEngine;
43 import org.apache.wss4j.dom.message.WSSecEncrypt;
44 import org.apache.wss4j.dom.message.WSSecHeader;
45 import org.apache.wss4j.dom.message.WSSecTimestamp;
46 import org.apache.wss4j.dom.message.WSSecUsernameToken;
47 import org.apache.wss4j.dom.message.token.UsernameToken;
48
49 import org.junit.jupiter.api.Test;
50 import org.w3c.dom.Document;
51
52 import static org.junit.jupiter.api.Assertions.assertEquals;
53 import static org.junit.jupiter.api.Assertions.assertTrue;
54 import static org.junit.jupiter.api.Assertions.fail;
55
56
57
58
59
60 public class FaultCodeTest implements CallbackHandler {
61 private WSSecurityEngine secEngine = new WSSecurityEngine();
62 private Crypto crypto;
63
64 public FaultCodeTest() throws Exception {
65 crypto = CryptoFactory.getInstance("wss40.properties");
66 WSSConfig.init();
67 }
68
69
70
71
72
73 @Test
74 public void testFailedCheck() throws Exception {
75 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
76 WSSecHeader secHeader = new WSSecHeader(doc);
77 secHeader.insertSecurityHeader();
78
79 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
80 builder.setUserInfo("wss40", "security");
81 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
82
83 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
84 SecretKey symmetricKey = keyGen.generateKey();
85 Document encryptedDoc = builder.build(crypto, symmetricKey);
86
87 try {
88 verify(encryptedDoc);
89 fail("Failure expected with a bad password");
90 } catch (WSSecurityException ex) {
91 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILED_CHECK);
92 assertEquals("The private key for the supplied alias does not exist in the keystore", ex.getMessage());
93 QName faultCode = new QName(WSConstants.WSSE_NS, "FailedCheck");
94 assertTrue(ex.getFaultCode().equals(faultCode));
95 }
96 }
97
98
99
100
101
102 @Test
103 public void testUnsupportedAlgorithm() throws Exception {
104 try {
105 secEngine.getWssConfig();
106 KeyUtils.getCipherInstance("Bad Algorithm");
107 fail("Failure expected on an unsupported algorithm");
108 } catch (WSSecurityException ex) {
109 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.UNSUPPORTED_ALGORITHM);
110 assertEquals("unsupported key transport encryption algorithm: No such algorithm: \"Bad Algorithm\"", ex.getMessage());
111 QName faultCode = new QName(WSConstants.WSSE_NS, "UnsupportedAlgorithm");
112 assertTrue(ex.getFaultCode().equals(faultCode));
113 }
114 }
115
116
117
118
119
120 @Test
121 public void testMessageExpired() throws Exception {
122 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
123 WSSecHeader secHeader = new WSSecHeader(doc);
124 secHeader.insertSecurityHeader();
125
126 WSSecTimestamp builder = new WSSecTimestamp(secHeader);
127 builder.setTimeToLive(-1);
128
129 Document timestampedDoc = builder.build();
130
131 try {
132 verify(timestampedDoc);
133 fail("Failure expected on an expired message");
134 } catch (WSSecurityException ex) {
135 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
136 assertEquals("Invalid timestamp: The message timestamp has expired", ex.getMessage());
137 QName faultCode = new QName(WSConstants.WSSE_NS, "MessageExpired");
138 assertTrue(ex.getFaultCode().equals(faultCode));
139 }
140 }
141
142
143
144
145
146 @Test
147 public void testFailedAuthentication() throws Exception {
148 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
149 WSSecHeader secHeader = new WSSecHeader(doc);
150 secHeader.insertSecurityHeader();
151
152 WSSecUsernameToken builder = new WSSecUsernameToken(secHeader);
153 builder.addCreated();
154 builder.addNonce();
155 builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
156
157 Document timestampedDoc = builder.build();
158
159 try {
160 verify(timestampedDoc);
161 fail("Failure expected on a bad password");
162 } catch (WSSecurityException ex) {
163 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
164 assertEquals("The security token could not be authenticated or authorized", ex.getMessage());
165 QName faultCode = new QName(WSConstants.WSSE_NS, "FailedAuthentication");
166 assertTrue(ex.getFaultCode().equals(faultCode));
167 }
168 }
169
170
171
172
173
174 @Test
175 public void testInvalidSecurityToken() throws Exception {
176 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
177 WSSecHeader secHeader = new WSSecHeader(doc);
178 secHeader.insertSecurityHeader();
179
180 WSSecUsernameToken builder = new WSSecUsernameToken(secHeader);
181 builder.addCreated();
182 builder.addNonce();
183 builder.setUserInfo(null, "security");
184
185 builder.build();
186
187 try {
188 new UsernameToken(doc.getDocumentElement(), false, new BSPEnforcer());
189 fail("Failure expected on an invalid security token");
190 } catch (WSSecurityException ex) {
191 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN);
192 assertEquals("Bad element, expected \"{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}UsernameToken\" while got \"{http://schemas.xmlsoap.org/soap/envelope/}Envelope\"", ex.getMessage());
193 QName faultCode = new QName(WSConstants.WSSE_NS, "InvalidSecurityToken");
194 assertTrue(ex.getFaultCode().equals(faultCode));
195 }
196 }
197
198
199
200
201 @Test
202 public void testInvalidSecurity() throws Exception {
203 try {
204 new Reference((org.w3c.dom.Element)null);
205 fail("Failure expected on processing the security header");
206 } catch (WSSecurityException ex) {
207 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
208 assertEquals("<Reference> token could not be retrieved", ex.getMessage());
209 QName faultCode = new QName(WSConstants.WSSE_NS, "InvalidSecurity");
210 assertTrue(ex.getFaultCode().equals(faultCode));
211 }
212 }
213
214
215
216
217
218
219
220
221 private void verify(Document doc) throws Exception {
222 secEngine.processSecurityHeader(doc, null, this, crypto);
223 }
224
225
226 public void handle(Callback[] callbacks)
227 throws IOException, UnsupportedCallbackException {
228 for (Callback callback : callbacks) {
229 if (callback instanceof WSPasswordCallback) {
230 WSPasswordCallback pc = (WSPasswordCallback) callback;
231
232
233
234 pc.setPassword("securit");
235 } else {
236 throw new UnsupportedCallbackException(callback, "Unrecognized Callback");
237 }
238 }
239 }
240
241 }