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.WSEncryptionPart;
23 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
24 import org.apache.wss4j.common.util.SOAPUtil;
25 import org.apache.wss4j.dom.SOAPConstants;
26 import org.apache.wss4j.dom.WSDataRef;
27 import org.apache.wss4j.dom.WSConstants;
28 import org.apache.wss4j.dom.common.CustomHandler;
29 import org.apache.wss4j.dom.common.SAML1CallbackHandler;
30
31 import org.apache.wss4j.dom.engine.WSSConfig;
32 import org.apache.wss4j.dom.engine.WSSecurityEngine;
33 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
34 import org.apache.wss4j.dom.handler.HandlerAction;
35 import org.apache.wss4j.dom.handler.RequestData;
36 import org.apache.wss4j.dom.handler.WSHandlerConstants;
37 import org.apache.wss4j.dom.handler.WSHandlerResult;
38 import org.apache.wss4j.common.crypto.Crypto;
39 import org.apache.wss4j.common.crypto.CryptoFactory;
40 import org.apache.wss4j.common.crypto.Merlin;
41 import org.apache.wss4j.common.ext.WSSecurityException;
42 import org.apache.wss4j.common.saml.SAMLCallback;
43 import org.apache.wss4j.common.saml.SAMLUtil;
44 import org.apache.wss4j.common.saml.builder.SAML1Constants;
45 import org.apache.wss4j.common.util.Loader;
46 import org.apache.wss4j.common.util.XMLUtils;
47 import org.apache.wss4j.dom.saml.SignedSamlTokenHOKTest;
48 import org.apache.wss4j.dom.saml.WSSecSignatureSAML;
49 import org.apache.wss4j.dom.util.WSSecurityUtil;
50
51 import org.junit.jupiter.api.Test;
52 import org.w3c.dom.Document;
53 import org.w3c.dom.Element;
54
55 import java.io.InputStream;
56 import java.security.KeyStore;
57 import java.util.ArrayList;
58 import java.util.List;
59
60 import javax.xml.namespace.QName;
61
62 import static org.junit.jupiter.api.Assertions.assertEquals;
63 import static org.junit.jupiter.api.Assertions.assertFalse;
64 import static org.junit.jupiter.api.Assertions.assertNotNull;
65 import static org.junit.jupiter.api.Assertions.assertTrue;
66 import static org.junit.jupiter.api.Assertions.fail;
67
68
69
70
71
72 public class SignaturePartsTest {
73 private static final org.slf4j.Logger LOG =
74 org.slf4j.LoggerFactory.getLogger(SignaturePartsTest.class);
75 private static final String SOAPMSG = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
76 "<soapenv:Envelope xmlns:foo=\"urn:foo.bar\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
77 " <soapenv:Header>" +
78 " <foo:foobar>baz</foo:foobar>" +
79 " </soapenv:Header>" +
80 " <soapenv:Body>" +
81 " <ns1:testMethod xmlns:ns1=\"http://axis/service/security/test6/LogTestService8\"></ns1:testMethod>" +
82 " </soapenv:Body>" +
83 "</soapenv:Envelope>";
84 private static final String SOAPMSG_MULTIPLE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
85 "<soapenv:Envelope xmlns:foo=\"urn:foo.bar\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
86 " <soapenv:Header>" +
87 " <foo:foobar>baz</foo:foobar>" +
88 " </soapenv:Header>" +
89 " <soapenv:Body>" +
90 " <ns1:testMethod xmlns:ns1=\"http://axis/service/security/test6/LogTestService8\">asf1</ns1:testMethod>" +
91 " <ns1:testMethod xmlns:ns1=\"http://axis/service/security/test6/LogTestService8\">asf2</ns1:testMethod>" +
92 " </soapenv:Body>" +
93 "</soapenv:Envelope>";
94
95 private WSSecurityEngine secEngine = new WSSecurityEngine();
96 private Crypto crypto;
97
98 public SignaturePartsTest() throws Exception {
99 WSSConfig.init();
100 crypto = CryptoFactory.getInstance();
101 }
102
103
104
105
106 @SuppressWarnings("unchecked")
107 @Test
108 public void testSOAPHeader() throws Exception {
109 Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
110 WSSecHeader secHeader = new WSSecHeader(doc);
111 secHeader.insertSecurityHeader();
112
113 WSSecSignature sign = new WSSecSignature(secHeader);
114 sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
115 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
116
117 WSEncryptionPart encP =
118 new WSEncryptionPart(
119 "foobar",
120 "urn:foo.bar",
121 "");
122 sign.getParts().add(encP);
123
124 Document signedDoc = sign.build(crypto);
125
126 if (LOG.isDebugEnabled()) {
127 String outputString =
128 XMLUtils.prettyDocumentToString(signedDoc);
129 LOG.debug(outputString);
130 }
131
132 WSHandlerResult results = verify(signedDoc);
133
134 WSSecurityEngineResult actionResult =
135 results.getActionResults().get(WSConstants.SIGN).get(0);
136 assertNotNull(actionResult);
137 assertFalse(actionResult.isEmpty());
138 final List<WSDataRef> refs =
139 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
140
141 WSDataRef wsDataRef = refs.get(0);
142 String xpath = wsDataRef.getXpath();
143 assertEquals("/soapenv:Envelope/soapenv:Header/foo:foobar", xpath);
144 assertEquals(WSConstants.RSA_SHA1, wsDataRef.getAlgorithm());
145 assertNotNull(wsDataRef.getDigestValue());
146 assertTrue(wsDataRef.getDigestValue().length > 0);
147 QName expectedQName = new QName("urn:foo.bar", "foobar");
148 assertEquals(expectedQName, wsDataRef.getName());
149
150 assertEquals(WSConstants.SHA1, wsDataRef.getDigestAlgorithm());
151
152 String sigMethod = (String)actionResult.get(WSSecurityEngineResult.TAG_SIGNATURE_METHOD);
153 assertEquals(WSConstants.RSA_SHA1, sigMethod);
154
155 String c14nMethod =
156 (String)actionResult.get(WSSecurityEngineResult.TAG_CANONICALIZATION_METHOD);
157 assertEquals(WSConstants.C14N_EXCL_OMIT_COMMENTS, c14nMethod);
158
159 List<String> transformAlgorithms = wsDataRef.getTransformAlgorithms();
160 assertTrue(transformAlgorithms.size() == 1);
161 assertTrue(WSConstants.C14N_EXCL_OMIT_COMMENTS.equals(transformAlgorithms.get(0)));
162 }
163
164 @Test
165 public void testOptionalSOAPHeaderPresent() throws Exception {
166 Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
167 WSSecHeader secHeader = new WSSecHeader(doc);
168 secHeader.insertSecurityHeader();
169
170 WSSecSignature sign = new WSSecSignature(secHeader);
171 sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
172 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
173
174 WSEncryptionPart encP =
175 new WSEncryptionPart(
176 "foobar",
177 "urn:foo.bar",
178 "");
179 encP.setRequired(false);
180 sign.getParts().add(encP);
181 String soapNamespace = WSSecurityUtil.getSOAPNamespace(doc.getDocumentElement());
182 encP =
183 new WSEncryptionPart(
184 WSConstants.ELEM_BODY,
185 soapNamespace,
186 "Content"
187 );
188 sign.getParts().add(encP);
189
190 Document signedDoc = sign.build(crypto);
191
192 if (LOG.isDebugEnabled()) {
193 String outputString =
194 XMLUtils.prettyDocumentToString(signedDoc);
195 LOG.debug(outputString);
196 }
197
198 verify(signedDoc);
199 }
200
201 @Test
202 public void testOptionalSOAPHeaderNotPresent() throws Exception {
203 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
204 WSSecHeader secHeader = new WSSecHeader(doc);
205 secHeader.insertSecurityHeader();
206
207 WSSecSignature sign = new WSSecSignature(secHeader);
208 sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
209 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
210
211 WSEncryptionPart encP =
212 new WSEncryptionPart(
213 "foobar",
214 "urn:foo.bar",
215 "");
216 encP.setRequired(false);
217 sign.getParts().add(encP);
218 String soapNamespace = WSSecurityUtil.getSOAPNamespace(doc.getDocumentElement());
219 encP =
220 new WSEncryptionPart(
221 WSConstants.ELEM_BODY,
222 soapNamespace,
223 "Content"
224 );
225 sign.getParts().add(encP);
226
227 Document signedDoc = sign.build(crypto);
228
229 if (LOG.isDebugEnabled()) {
230 String outputString =
231 XMLUtils.prettyDocumentToString(signedDoc);
232 LOG.debug(outputString);
233 }
234
235 verify(signedDoc);
236 }
237
238 @Test
239 public void testRequiredSOAPHeaderNotPresent() throws Exception {
240 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
241 WSSecHeader secHeader = new WSSecHeader(doc);
242 secHeader.insertSecurityHeader();
243
244 WSSecSignature sign = new WSSecSignature(secHeader);
245 sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
246 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
247
248 WSEncryptionPart encP =
249 new WSEncryptionPart(
250 "foobar",
251 "urn:foo.bar",
252 "");
253 sign.getParts().add(encP);
254 String soapNamespace = WSSecurityUtil.getSOAPNamespace(doc.getDocumentElement());
255 encP =
256 new WSEncryptionPart(
257 WSConstants.ELEM_BODY,
258 soapNamespace,
259 "Content"
260 );
261 sign.getParts().add(encP);
262
263 try {
264 sign.build(crypto);
265 fail("Failure expected on not signing a required element");
266 } catch (WSSecurityException ex) {
267 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILED_SIGNATURE);
268 }
269 }
270
271
272
273
274 @SuppressWarnings("unchecked")
275 @Test
276 public void testSOAPHeaderSTRTransform() throws Exception {
277
278 Crypto issuerCrypto = new Merlin();
279 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
280 ClassLoader loader = Loader.getClassLoader(SignedSamlTokenHOKTest.class);
281 InputStream input = Merlin.loadInputStream(loader, "keys/wss40_server.jks");
282 keyStore.load(input, "security".toCharArray());
283 input.close();
284 ((Merlin)issuerCrypto).setKeyStore(keyStore);
285
286 Crypto userCrypto = CryptoFactory.getInstance("wss40.properties");
287
288 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
289 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
290 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
291
292 SAMLCallback samlCallback = new SAMLCallback();
293 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
294
295 samlCallback.setIssuer("www.example.com");
296
297 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
298 samlAssertion.signAssertion("wss40_server", "security", issuerCrypto, false);
299
300 Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
301 WSSecHeader secHeader = new WSSecHeader(doc);
302 secHeader.insertSecurityHeader();
303
304 WSSecSignatureSAML wsSign = new WSSecSignatureSAML(secHeader);
305 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
306 wsSign.setUserInfo("wss40", "security");
307
308 WSEncryptionPart encP =
309 new WSEncryptionPart("STRTransform", "", "Element");
310 wsSign.getParts().add(encP);
311
312
313
314
315 Document signedDoc = wsSign.build(userCrypto, samlAssertion, null, null, null);
316
317 if (LOG.isDebugEnabled()) {
318 LOG.debug("Signed SAML message (key holder):");
319 String outputString =
320 XMLUtils.prettyDocumentToString(signedDoc);
321 LOG.debug(outputString);
322 }
323
324
325 Crypto trustCrypto = new Merlin();
326 KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
327 input = Merlin.loadInputStream(loader, "keys/wss40CA.jks");
328 trustStore.load(input, "security".toCharArray());
329 input.close();
330 ((Merlin)trustCrypto).setTrustStore(trustStore);
331
332 WSHandlerResult results =
333 secEngine.processSecurityHeader(doc, null, null, trustCrypto);
334 WSSecurityEngineResult stUnsignedActionResult =
335 results.getActionResults().get(WSConstants.ST_SIGNED).get(0);
336 SamlAssertionWrapper receivedSamlAssertion =
337 (SamlAssertionWrapper) stUnsignedActionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
338 assertNotNull(receivedSamlAssertion);
339 assertTrue(receivedSamlAssertion.isSigned());
340
341 WSSecurityEngineResult signActionResult =
342 results.getActionResults().get(WSConstants.SIGN).get(0);
343 assertNotNull(signActionResult);
344 assertFalse(signActionResult.isEmpty());
345 final List<WSDataRef> refs =
346 (List<WSDataRef>) signActionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
347
348 WSDataRef wsDataRef = refs.get(0);
349 String xpath = wsDataRef.getXpath();
350 assertEquals("/soapenv:Envelope/soapenv:Header/wsse:Security/saml1:Assertion", xpath);
351 }
352
353
354
355
356 @Test
357 public void testBadLocalname() throws Exception {
358 Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
359 WSSecHeader secHeader = new WSSecHeader(doc);
360 secHeader.insertSecurityHeader();
361
362 WSSecSignature sign = new WSSecSignature(secHeader);
363 sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
364 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
365
366 WSEncryptionPart encP =
367 new WSEncryptionPart(
368 "foobar2",
369 "urn:foo.bar",
370 "");
371 sign.getParts().add(encP);
372
373 try {
374 sign.build(crypto);
375 fail("Failure expected on a bad localname");
376 } catch (WSSecurityException ex) {
377 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILED_SIGNATURE);
378 }
379 }
380
381
382
383
384 @Test
385 public void testBadNamespace() throws Exception {
386 Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
387 WSSecHeader secHeader = new WSSecHeader(doc);
388 secHeader.insertSecurityHeader();
389
390 WSSecSignature sign = new WSSecSignature(secHeader);
391 sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
392 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
393
394 WSEncryptionPart encP =
395 new WSEncryptionPart(
396 "foobar",
397 "urn:foo.bar2",
398 "");
399 sign.getParts().add(encP);
400
401 try {
402 sign.build(crypto);
403 fail("Failure expected on a bad namespace");
404 } catch (WSSecurityException ex) {
405 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILED_SIGNATURE);
406 }
407 }
408
409
410
411
412 @Test
413 public void testSOAPHeaderAndBody() throws Exception {
414 Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
415 WSSecHeader secHeader = new WSSecHeader(doc);
416 secHeader.insertSecurityHeader();
417
418 WSSecSignature sign = new WSSecSignature(secHeader);
419 sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
420 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
421
422 SOAPConstants soapConstants =
423 WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
424
425 WSEncryptionPart encP =
426 new WSEncryptionPart(
427 soapConstants.getBodyQName().getLocalPart(),
428 soapConstants.getEnvelopeURI(),
429 "");
430 sign.getParts().add(encP);
431 WSEncryptionPart encP2 =
432 new WSEncryptionPart(
433 "foobar",
434 "urn:foo.bar",
435 "");
436 sign.getParts().add(encP2);
437
438 Document signedDoc = sign.build(crypto);
439
440 if (LOG.isDebugEnabled()) {
441 String outputString =
442 XMLUtils.prettyDocumentToString(signedDoc);
443 LOG.debug(outputString);
444 }
445
446 WSHandlerResult results = verify(signedDoc);
447
448 QName fooName = new QName("urn:foo.bar", "foobar");
449 QName bodyName = new QName(soapConstants.getEnvelopeURI(), "Body");
450 QName headerName = new QName(soapConstants.getEnvelopeURI(), "Header");
451
452 WSSecurityEngineResult actionResult =
453 results.getActionResults().get(WSConstants.SIGN).get(0);
454 assertNotNull(actionResult);
455 assertFalse(actionResult.isEmpty());
456
457 @SuppressWarnings("unchecked")
458 final List<WSDataRef> refs =
459 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
460 assertTrue(refs != null && !refs.isEmpty());
461
462 boolean foundFoo = false;
463 boolean foundBody = false;
464 boolean foundHeader = false;
465 for (WSDataRef ref : refs) {
466 if (fooName.equals(ref.getName())) {
467 foundFoo = true;
468 } else if (bodyName.equals(ref.getName())) {
469 foundBody = true;
470 } else if (headerName.equals(ref.getName())) {
471 foundHeader = true;
472 }
473 }
474 assertTrue(foundFoo && foundBody);
475 assertFalse(foundHeader);
476 }
477
478
479
480
481
482 @Test
483 public void testSignaturePartDOMElement() throws Exception {
484 Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
485 WSSecHeader secHeader = new WSSecHeader(doc);
486 secHeader.insertSecurityHeader();
487
488 WSSecSignature sign = new WSSecSignature(secHeader);
489 sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
490 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
491
492 SOAPConstants soapConstants =
493 WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
494
495
496 WSEncryptionPart encP =
497 new WSEncryptionPart(
498 "Incorrect Localname",
499 "Incorrect N/S",
500 "");
501 Element bodyElement = WSSecurityUtil.findBodyElement(doc);
502 assertTrue(bodyElement != null && "Body".equals(bodyElement.getLocalName()));
503 encP.setElement(bodyElement);
504 sign.getParts().add(encP);
505
506 Document signedDoc = sign.build(crypto);
507
508 if (LOG.isDebugEnabled()) {
509 String outputString =
510 XMLUtils.prettyDocumentToString(signedDoc);
511 LOG.debug(outputString);
512 }
513
514 WSHandlerResult results = verify(signedDoc);
515
516 WSSecurityEngineResult actionResult =
517 results.getActionResults().get(WSConstants.SIGN).get(0);
518 assertNotNull(actionResult);
519 assertFalse(actionResult.isEmpty());
520 @SuppressWarnings("unchecked")
521 final List<WSDataRef> refs =
522 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
523
524 WSDataRef wsDataRef = refs.get(0);
525 QName bodyName = new QName(soapConstants.getEnvelopeURI(), "Body");
526 assertEquals(bodyName, wsDataRef.getName());
527 }
528
529
530
531
532 @Test
533 public void testMultipleElements() throws Exception {
534 Document doc = SOAPUtil.toSOAPPart(SOAPMSG_MULTIPLE);
535 WSSecHeader secHeader = new WSSecHeader(doc);
536 secHeader.insertSecurityHeader();
537
538 WSSecSignature sign = new WSSecSignature(secHeader);
539 sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
540 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
541
542 WSEncryptionPart encP =
543 new WSEncryptionPart(
544 "testMethod",
545 "http://axis/service/security/test6/LogTestService8",
546 "");
547 sign.getParts().add(encP);
548
549 Document signedDoc = sign.build(crypto);
550
551 String outputString =
552 XMLUtils.prettyDocumentToString(signedDoc);
553 if (LOG.isDebugEnabled()) {
554 LOG.debug(outputString);
555 }
556
557 verify(signedDoc);
558 }
559
560 @Test
561 public void testSignedKeyInfo() throws Exception {
562 Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
563 WSSecHeader secHeader = new WSSecHeader(doc);
564 secHeader.insertSecurityHeader();
565
566 WSSecSignature sign = new WSSecSignature(secHeader);
567 sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
568 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
569
570 WSEncryptionPart encP =
571 new WSEncryptionPart(
572 "KeyInfo",
573 WSConstants.SIG_NS,
574 "");
575 sign.getParts().add(encP);
576
577 Document signedDoc = sign.build(crypto);
578
579 if (LOG.isDebugEnabled()) {
580 String outputString =
581 XMLUtils.prettyDocumentToString(signedDoc);
582 LOG.debug(outputString);
583 }
584
585 WSHandlerResult results = verify(signedDoc);
586
587 verifySignedKeyInfoResults(results);
588 }
589
590 @Test
591 public void testSignedKeyInfoAction() throws Exception {
592 final WSSConfig cfg = WSSConfig.getNewInstance();
593 final RequestData reqData = new RequestData();
594 reqData.setWssConfig(cfg);
595 reqData.setUsername("16c73ab6-b892-458f-abf5-2f875f74882e");
596
597 java.util.Map<String, Object> config = new java.util.TreeMap<>();
598 config.put(WSHandlerConstants.SIG_PROP_FILE, "crypto.properties");
599 config.put("password", "security");
600 config.put(
601 WSHandlerConstants.SIGNATURE_PARTS, "{}{" + WSConstants.SIG_NS + "}KeyInfo"
602 );
603 reqData.setMsgContext(config);
604
605 final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
606 CustomHandler handler = new CustomHandler();
607 List<HandlerAction> actions = new ArrayList<>();
608 actions.add(new HandlerAction(WSConstants.SIGN));
609 handler.send(
610 doc,
611 reqData,
612 actions,
613 true
614 );
615 String outputString =
616 XMLUtils.prettyDocumentToString(doc);
617 if (LOG.isDebugEnabled()) {
618 LOG.debug("Signed message:");
619 LOG.debug(outputString);
620 }
621
622 WSHandlerResult results = verify(doc);
623
624 List<Integer> receivedActions = new ArrayList<>();
625 receivedActions.add(WSConstants.SIGN);
626 assertTrue(handler.checkResults(results.getResults(), receivedActions));
627
628 verifySignedKeyInfoResults(results);
629 }
630
631 private void verifySignedKeyInfoResults(WSHandlerResult results) {
632
633 WSSecurityEngineResult actionResult =
634 results.getActionResults().get(WSConstants.SIGN).get(0);
635 assertNotNull(actionResult);
636 assertFalse(actionResult.isEmpty());
637 final List<WSDataRef> refs =
638 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
639
640 WSDataRef wsDataRef = refs.get(0);
641 String xpath = wsDataRef.getXpath();
642 assertTrue(xpath.matches("/(soapenv|SOAP-ENV):Envelope/(soapenv|SOAP-ENV):Header/wsse:Security/ds:Signature/ds:KeyInfo"));
643 assertEquals(WSConstants.RSA_SHA1, wsDataRef.getAlgorithm());
644 assertNotNull(wsDataRef.getDigestValue());
645 assertTrue(wsDataRef.getDigestValue().length > 0);
646 QName expectedQName = new QName(WSConstants.SIG_NS, "KeyInfo");
647 assertEquals(expectedQName, wsDataRef.getName());
648
649 assertEquals(WSConstants.SHA1, wsDataRef.getDigestAlgorithm());
650
651 String sigMethod = (String)actionResult.get(WSSecurityEngineResult.TAG_SIGNATURE_METHOD);
652 assertEquals(WSConstants.RSA_SHA1, sigMethod);
653
654 String c14nMethod =
655 (String)actionResult.get(WSSecurityEngineResult.TAG_CANONICALIZATION_METHOD);
656 assertEquals(WSConstants.C14N_EXCL_OMIT_COMMENTS, c14nMethod);
657
658 List<String> transformAlgorithms = wsDataRef.getTransformAlgorithms();
659 assertTrue(transformAlgorithms.size() == 1);
660 assertTrue(WSConstants.C14N_EXCL_OMIT_COMMENTS.equals(transformAlgorithms.get(0)));
661 }
662
663
664
665
666
667
668
669
670 private WSHandlerResult verify(Document doc) throws Exception {
671 WSHandlerResult results =
672 secEngine.processSecurityHeader(doc, null, null, crypto);
673 if (LOG.isDebugEnabled()) {
674 LOG.debug("Verfied and decrypted message:");
675 String outputString =
676 XMLUtils.prettyDocumentToString(doc);
677 LOG.debug(outputString);
678 }
679 return results;
680 }
681
682 }