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.message;
21
22 import org.apache.wss4j.common.util.SOAPUtil;
23 import org.apache.wss4j.dom.WSConstants;
24 import org.apache.wss4j.dom.WSDataRef;
25 import org.apache.wss4j.dom.common.CustomHandler;
26 import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
27
28 import org.apache.wss4j.dom.engine.WSSConfig;
29 import org.apache.wss4j.dom.engine.WSSecurityEngine;
30 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
31 import org.apache.wss4j.dom.handler.HandlerAction;
32 import org.apache.wss4j.dom.handler.RequestData;
33 import org.apache.wss4j.dom.handler.WSHandlerConstants;
34 import org.apache.wss4j.dom.handler.WSHandlerResult;
35
36 import org.junit.jupiter.api.Test;
37 import org.apache.wss4j.common.WSEncryptionPart;
38 import org.apache.wss4j.common.crypto.Crypto;
39 import org.apache.wss4j.common.crypto.CryptoFactory;
40 import org.apache.wss4j.common.util.KeyUtils;
41 import org.apache.wss4j.common.util.XMLUtils;
42 import org.w3c.dom.Document;
43
44 import javax.crypto.KeyGenerator;
45 import javax.crypto.SecretKey;
46 import javax.security.auth.callback.CallbackHandler;
47 import javax.xml.crypto.dsig.SignatureMethod;
48
49 import java.util.List;
50 import java.util.ArrayList;
51
52 import static org.junit.jupiter.api.Assertions.assertEquals;
53 import static org.junit.jupiter.api.Assertions.assertNotNull;
54 import static org.junit.jupiter.api.Assertions.assertNull;
55 import static org.junit.jupiter.api.Assertions.assertTrue;
56
57
58
59
60 public class SignatureEncryptionTest {
61 private static final org.slf4j.Logger LOG =
62 org.slf4j.LoggerFactory.getLogger(SignatureEncryptionTest.class);
63 private static final String SOAPMSG =
64 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
65 + "<SOAP-ENV:Envelope "
66 + "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
67 + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
68 + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
69 + "<SOAP-ENV:Body>"
70 + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">"
71 + "<value xmlns=\"http://blah.com\">15</value>"
72 + "</add>"
73 + "</SOAP-ENV:Body>"
74 + "</SOAP-ENV:Envelope>";
75 public static final String SAMPLE_SOAP12_FAULT_MSG =
76 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
77 + "<s:Envelope "
78 + "xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" "
79 + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
80 + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
81 + "<s:Body>"
82 + "<Fault xmlns=\"http://www.w3.org/2003/05/soap-envelope\"><Code><Value>Receiver</Value></Code><Reason>"
83 + "<Text xml:lang=\"en\">Error Message.</Text></Reason></Fault>"
84 + "</s:Body>"
85 + "</s:Envelope>";
86
87 private WSSecurityEngine secEngine = new WSSecurityEngine();
88 private CallbackHandler callbackHandler = new KeystoreCallbackHandler();
89
90 private Crypto crypto;
91
92 public SignatureEncryptionTest() throws Exception {
93 crypto = CryptoFactory.getInstance("wss40.properties");
94 WSSConfig.init();
95 }
96
97
98
99
100
101
102
103
104
105 @Test
106 public void testEncryptionSigning() throws Exception {
107 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
108 WSSecHeader secHeader = new WSSecHeader(doc);
109 secHeader.insertSecurityHeader();
110
111 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
112 WSSecSignature sign = new WSSecSignature(secHeader);
113 encrypt.setUserInfo("wss40");
114 sign.setUserInfo("wss40", "security");
115 LOG.info("Before Encryption....");
116
117 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
118 SecretKey symmetricKey = keyGen.generateKey();
119 Document encryptedDoc = encrypt.build(crypto, symmetricKey);
120
121 if (LOG.isDebugEnabled()) {
122 LOG.debug("After Encryption....");
123 String outputString =
124 XMLUtils.prettyDocumentToString(encryptedDoc);
125 LOG.debug(outputString);
126 }
127
128 Document encryptedSignedDoc = sign.build(crypto);
129
130 if (LOG.isDebugEnabled()) {
131 LOG.debug("After Signing....");
132 String outputString =
133 XMLUtils.prettyDocumentToString(encryptedSignedDoc);
134 LOG.debug(outputString);
135 }
136 verify(encryptedSignedDoc);
137 }
138
139
140
141
142
143
144
145
146
147
148 @SuppressWarnings("unchecked")
149 @Test
150 public void testEncryptionElementSigning() throws Exception {
151 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
152 WSSecHeader secHeader = new WSSecHeader(doc);
153 secHeader.insertSecurityHeader();
154
155 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
156 WSSecSignature sign = new WSSecSignature(secHeader);
157 encrypt.setUserInfo("wss40");
158 sign.setUserInfo("wss40", "security");
159 LOG.info("Before Encryption....");
160
161 WSEncryptionPart part =
162 new WSEncryptionPart(
163 "add",
164 "http://ws.apache.org/counter/counter_port_type",
165 "Element");
166 encrypt.getParts().add(part);
167
168 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
169 SecretKey symmetricKey = keyGen.generateKey();
170 Document encryptedDoc = encrypt.build(crypto, symmetricKey);
171
172 if (LOG.isDebugEnabled()) {
173 LOG.debug("After Encryption....");
174 String outputString =
175 XMLUtils.prettyDocumentToString(encryptedDoc);
176 LOG.debug(outputString);
177 }
178
179 WSEncryptionPart signPart =
180 new WSEncryptionPart(
181 WSConstants.ENC_DATA_LN,
182 WSConstants.ENC_NS,
183 "Element");
184 sign.getParts().add(signPart);
185
186 Document encryptedSignedDoc = sign.build(crypto);
187
188 if (LOG.isDebugEnabled()) {
189 LOG.debug("After Signing....");
190 String outputString =
191 XMLUtils.prettyDocumentToString(encryptedSignedDoc);
192 LOG.debug(outputString);
193 }
194
195 WSHandlerResult results = verify(encryptedSignedDoc);
196
197 List<WSSecurityEngineResult> sigSecEngResults =
198 results.getActionResults().get(WSConstants.SIGN);
199
200 List<WSSecurityEngineResult> encSecEngResults =
201 results.getActionResults().get(WSConstants.ENCR);
202
203 assertEquals(1, sigSecEngResults.size());
204 assertEquals(1, encSecEngResults.size());
205
206 List<WSDataRef> sigDataRefs =
207 (List<WSDataRef>)(sigSecEngResults.get(0)).get(
208 WSSecurityEngineResult.TAG_DATA_REF_URIS
209 );
210
211 List<WSDataRef> encDataRefs =
212 (List<WSDataRef>)(encSecEngResults.get(0)).get(
213 WSSecurityEngineResult.TAG_DATA_REF_URIS
214 );
215
216 assertNotNull(sigDataRefs);
217 assertNotNull(encDataRefs);
218 assertEquals(1, sigDataRefs.size());
219 assertEquals(1, encDataRefs.size());
220
221 assertNull(sigDataRefs.get(0)
222 .getProtectedElement().getAttributeNodeNS(WSConstants.WSU_NS, "Id"));
223
224 assertTrue(sigDataRefs.get(0).getWsuId().contains(
225 encDataRefs.get(0).getWsuId()));
226 }
227
228
229
230
231
232
233
234
235
236
237 @Test
238 public void testSigningEncryption() throws Exception {
239 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
240 WSSecHeader secHeader = new WSSecHeader(doc);
241 secHeader.insertSecurityHeader();
242
243 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
244 WSSecSignature sign = new WSSecSignature(secHeader);
245 encrypt.setUserInfo("wss40");
246 sign.setUserInfo("wss40", "security");
247 LOG.info("Before Encryption....");
248
249 sign.build(crypto);
250
251 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
252 SecretKey symmetricKey = keyGen.generateKey();
253 Document encryptedSignedDoc = encrypt.build(crypto, symmetricKey);
254 LOG.info("After Encryption....");
255 verify(encryptedSignedDoc);
256 }
257
258
259
260
261
262
263
264 @Test
265 public void testWSS198() throws Exception {
266 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
267 WSSecHeader secHeader = new WSSecHeader(doc);
268 secHeader.insertSecurityHeader();
269
270 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
271 WSSecSignature sign = new WSSecSignature(secHeader);
272 encrypt.setUserInfo("wss40");
273 sign.setUserInfo("wss40", "security");
274 LOG.info("Before Encryption....");
275
276 WSEncryptionPart encP =
277 new WSEncryptionPart(
278 "add",
279 "http://ws.apache.org/counter/counter_port_type",
280 "");
281 encrypt.getParts().add(encP);
282
283 sign.build(crypto);
284
285 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
286 SecretKey symmetricKey = keyGen.generateKey();
287 Document encryptedSignedDoc = encrypt.build(crypto, symmetricKey);
288 LOG.info("WSS198");
289 if (LOG.isDebugEnabled()) {
290 String outputString =
291 XMLUtils.prettyDocumentToString(encryptedSignedDoc);
292 LOG.debug(outputString);
293 }
294 verify(encryptedSignedDoc);
295 }
296
297
298
299
300
301
302
303
304
305
306 @Test
307 public void testSigningEncryptionIS3DES() throws Exception {
308 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
309 WSSecHeader secHeader = new WSSecHeader(doc);
310 secHeader.insertSecurityHeader();
311
312 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
313 encrypt.setUserInfo("wss40");
314 encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
315 encrypt.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
316
317 WSSecSignature sign = new WSSecSignature(secHeader);
318 sign.setUserInfo("wss40", "security");
319 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
320
321 LOG.info("Before Sign/Encryption....");
322
323 sign.build(crypto);
324
325 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.TRIPLE_DES);
326 SecretKey symmetricKey = keyGen.generateKey();
327 Document encryptedSignedDoc = encrypt.build(crypto, symmetricKey);
328 if (LOG.isDebugEnabled()) {
329 LOG.debug("Signed and encrypted message with IssuerSerial key identifier (both), 3DES:");
330 String outputString =
331 XMLUtils.prettyDocumentToString(encryptedSignedDoc);
332 LOG.debug(outputString);
333 }
334
335 LOG.info("After Sign/Encryption....");
336 verify(encryptedSignedDoc);
337 }
338
339
340
341
342
343
344
345 @Test
346 public void testEncryptedKeySignature() throws Exception {
347 Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
348 LOG.info("Before Sign/Encryption....");
349
350 WSSecHeader secHeader = new WSSecHeader(doc);
351 secHeader.insertSecurityHeader();
352
353 WSSecEncryptedKey encrKey = new WSSecEncryptedKey(secHeader);
354 encrKey.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
355 encrKey.setUserInfo("wss40", "security");
356
357 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_192);
358 SecretKey symmetricKey = keyGen.generateKey();
359 encrKey.prepare(crypto, symmetricKey);
360
361 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
362 encrypt.setEncKeyId(encrKey.getId());
363 encrypt.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
364 encrypt.setEncryptSymmKey(false);
365 encrypt.setEncryptedKeyElement(encrKey.getEncryptedKeyElement());
366
367 WSSecSignature sign = new WSSecSignature(secHeader);
368 sign.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
369 sign.setCustomTokenId(encrKey.getId());
370 sign.setSecretKey(symmetricKey.getEncoded());
371 sign.setCustomTokenValueType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
372 sign.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
373
374 sign.build(crypto);
375 Document encryptedSignedDoc = encrypt.build(crypto, symmetricKey);
376
377 if (LOG.isDebugEnabled()) {
378 LOG.debug("Signed and encrypted message with IssuerSerial key identifier (both), 3DES:");
379 String outputString =
380 XMLUtils.prettyDocumentToString(encryptedSignedDoc);
381 LOG.debug(outputString);
382 }
383
384 LOG.info("After Sign/Encryption....");
385 verify(encryptedSignedDoc);
386 }
387
388 @Test
389 public void testEncryptionSigningHandler() throws Exception {
390 final WSSConfig cfg = WSSConfig.getNewInstance();
391 final RequestData reqData = new RequestData();
392 reqData.setWssConfig(cfg);
393 java.util.Map<String, Object> messageContext = new java.util.TreeMap<>();
394 messageContext.put(WSHandlerConstants.PW_CALLBACK_REF, new KeystoreCallbackHandler());
395 messageContext.put(WSHandlerConstants.ENC_PROP_REF_ID, "" + crypto.hashCode());
396 messageContext.put(WSHandlerConstants.SIG_PROP_REF_ID, "" + crypto.hashCode());
397 messageContext.put("" + crypto.hashCode(), crypto);
398 reqData.setMsgContext(messageContext);
399 reqData.setUsername("wss40");
400
401 final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
402 CustomHandler handler = new CustomHandler();
403 List<HandlerAction> handlerActions = new ArrayList<>();
404 HandlerAction action = new HandlerAction(WSConstants.ENCR);
405 handlerActions.add(action);
406 action = new HandlerAction(WSConstants.SIGN);
407 handlerActions.add(action);
408
409 handler.send(
410 doc,
411 reqData,
412 handlerActions,
413 true
414 );
415
416 String outputString =
417 XMLUtils.prettyDocumentToString(doc);
418 if (LOG.isDebugEnabled()) {
419 LOG.debug(outputString);
420 }
421
422 List<Integer> receivingActions = new ArrayList<>();
423 receivingActions.add(WSConstants.ENCR);
424 receivingActions.add(WSConstants.SIGN);
425 messageContext.put(WSHandlerConstants.DEC_PROP_REF_ID, "" + crypto.hashCode());
426 messageContext.put(WSHandlerConstants.SIG_VER_PROP_REF_ID, "" + crypto.hashCode());
427 handler.receive(receivingActions, reqData);
428
429 WSSecurityEngine newEngine = new WSSecurityEngine();
430 newEngine.processSecurityHeader(doc, reqData);
431 }
432
433 @Test
434 public void testSigningEncryptionHandler() throws Exception {
435 final WSSConfig cfg = WSSConfig.getNewInstance();
436 final RequestData reqData = new RequestData();
437 reqData.setWssConfig(cfg);
438 java.util.Map<String, Object> messageContext = new java.util.TreeMap<>();
439 messageContext.put(WSHandlerConstants.PW_CALLBACK_REF, new KeystoreCallbackHandler());
440 messageContext.put(WSHandlerConstants.ENC_PROP_REF_ID, "" + crypto.hashCode());
441 messageContext.put(WSHandlerConstants.SIG_PROP_REF_ID, "" + crypto.hashCode());
442 messageContext.put("" + crypto.hashCode(), crypto);
443 reqData.setMsgContext(messageContext);
444 reqData.setUsername("wss40");
445
446 final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
447 CustomHandler handler = new CustomHandler();
448 List<HandlerAction> handlerActions = new ArrayList<>();
449 HandlerAction action = new HandlerAction(WSConstants.SIGN);
450 handlerActions.add(action);
451 action = new HandlerAction(WSConstants.ENCR);
452 handlerActions.add(action);
453
454 handler.send(
455 doc,
456 reqData,
457 handlerActions,
458 true
459 );
460
461 String outputString =
462 XMLUtils.prettyDocumentToString(doc);
463 if (LOG.isDebugEnabled()) {
464 LOG.debug(outputString);
465 }
466
467 List<Integer> receivingActions = new ArrayList<>();
468 receivingActions.add(WSConstants.SIGN);
469 receivingActions.add(WSConstants.ENCR);
470 messageContext.put(WSHandlerConstants.DEC_PROP_REF_ID, "" + crypto.hashCode());
471 messageContext.put(WSHandlerConstants.SIG_VER_PROP_REF_ID, "" + crypto.hashCode());
472 handler.receive(receivingActions, reqData);
473
474 WSSecurityEngine newEngine = new WSSecurityEngine();
475 newEngine.processSecurityHeader(doc, reqData);
476 }
477
478 @Test
479 public void testSigningEncryptionSOAP12Fault() throws Exception {
480 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
481 WSSecHeader secHeader = new WSSecHeader(doc);
482 secHeader.insertSecurityHeader();
483
484 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
485 WSSecSignature sign = new WSSecSignature(secHeader);
486 encrypt.setUserInfo("wss40");
487 sign.setUserInfo("wss40", "security");
488 LOG.info("Before Encryption....");
489
490 sign.build(crypto);
491
492 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
493 SecretKey symmetricKey = keyGen.generateKey();
494 Document encryptedSignedDoc = encrypt.build(crypto, symmetricKey);
495
496 LOG.info("After Encryption....");
497 verify(encryptedSignedDoc);
498 }
499
500
501
502
503
504
505
506
507
508
509
510 private WSHandlerResult verify(Document doc) throws Exception {
511 WSHandlerResult resultList =
512 secEngine.processSecurityHeader(doc, null, callbackHandler, crypto);
513 if (LOG.isDebugEnabled()) {
514 String outputString =
515 XMLUtils.prettyDocumentToString(doc);
516 LOG.debug(outputString);
517 }
518
519 return resultList;
520 }
521
522 }