View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.wss4j.dom.message;
21  
22  import org.apache.wss4j.common.util.SOAPUtil;
23  import org.apache.wss4j.dom.SOAPConstants;
24  import org.apache.wss4j.dom.WSDataRef;
25  import org.apache.wss4j.dom.WSConstants;
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.WSHandlerResult;
32  import org.apache.wss4j.common.WSEncryptionPart;
33  import org.apache.wss4j.common.crypto.Crypto;
34  import org.apache.wss4j.common.crypto.CryptoFactory;
35  import org.apache.wss4j.common.ext.WSSecurityException;
36  import org.apache.wss4j.common.util.KeyUtils;
37  import org.apache.wss4j.common.util.XMLUtils;
38  import org.apache.wss4j.dom.util.WSSecurityUtil;
39  
40  import org.junit.jupiter.api.Test;
41  import org.w3c.dom.Document;
42  import org.w3c.dom.Element;
43  
44  import javax.crypto.KeyGenerator;
45  import javax.crypto.SecretKey;
46  import javax.security.auth.callback.CallbackHandler;
47  import javax.xml.namespace.QName;
48  
49  import java.util.List;
50  
51  import static org.junit.jupiter.api.Assertions.assertEquals;
52  import static org.junit.jupiter.api.Assertions.assertFalse;
53  import static org.junit.jupiter.api.Assertions.assertNotNull;
54  import static org.junit.jupiter.api.Assertions.assertTrue;
55  import static org.junit.jupiter.api.Assertions.fail;
56  
57  /**
58   * This is some unit tests for encryption using encryption using parts. Note that the "soapMsg" below
59   * has a custom header added.
60   */
61  public class EncryptionPartsTest {
62      private static final org.slf4j.Logger LOG =
63          org.slf4j.LoggerFactory.getLogger(EncryptionPartsTest.class);
64      private static final String SOAPMSG = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
65              "<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\">" +
66              "   <soapenv:Header>" +
67              "       <foo:bar1>baz1</foo:bar1>" +
68              "       <foo:foobar>baz</foo:foobar>" +
69              "       <foo:bar2>baz2</foo:bar2>" +
70              "       <foo:with-attributes some-attribute=\"3\">baz</foo:with-attributes>" +
71              "   </soapenv:Header>" +
72              "   <soapenv:Body>" +
73              "      <ns1:testMethod xmlns:ns1=\"http://axis/service/security/test6/LogTestService8\"></ns1:testMethod>" +
74              "   </soapenv:Body>" +
75              "</soapenv:Envelope>";
76      private static final String SOAPMSG_MULTIPLE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
77          "<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\">" +
78          "   <soapenv:Header>" +
79          "       <foo:foobar>baz</foo:foobar>" +
80          "   </soapenv:Header>" +
81          "   <soapenv:Body>" +
82          "      <ns1:testMethod xmlns:ns1=\"http://axis/service/security/test6/LogTestService8\">asf1</ns1:testMethod>" +
83          "      <ns1:testMethod xmlns:ns1=\"http://axis/service/security/test6/LogTestService8\">asf2</ns1:testMethod>" +
84          "   </soapenv:Body>" +
85          "</soapenv:Envelope>";
86  
87      private WSSecurityEngine secEngine = new WSSecurityEngine();
88      private CallbackHandler callbackHandler = new KeystoreCallbackHandler();
89      private Crypto crypto;
90  
91      public EncryptionPartsTest() throws Exception {
92          crypto = CryptoFactory.getInstance();
93          WSSConfig.init();
94      }
95  
96      /**
97       * Test encrypting a custom SOAP header
98       */
99      @SuppressWarnings("unchecked")
100     @Test
101     public void testSOAPHeader() throws Exception {
102         Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
103         WSSecHeader secHeader = new WSSecHeader(doc);
104         secHeader.insertSecurityHeader();
105 
106         WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
107         encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
108         encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
109 
110         WSEncryptionPart encP =
111             new WSEncryptionPart(
112                 "foobar",
113                 "urn:foo.bar",
114                 "");
115         encrypt.getParts().add(encP);
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             String outputString =
123                 XMLUtils.prettyDocumentToString(encryptedDoc);
124             LOG.debug(outputString);
125         }
126 
127         WSHandlerResult results = verify(encryptedDoc);
128 
129         WSSecurityEngineResult actionResult =
130             results.getActionResults().get(WSConstants.ENCR).get(0);
131         assertNotNull(actionResult);
132         assertFalse(actionResult.isEmpty());
133         final List<WSDataRef> refs =
134             (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
135 
136         assertEquals(WSConstants.KEYTRANSPORT_RSAOAEP,
137                 actionResult.get(WSSecurityEngineResult.TAG_ENCRYPTED_KEY_TRANSPORT_METHOD));
138 
139         WSDataRef wsDataRef = refs.get(0);
140         String xpath = wsDataRef.getXpath();
141         assertEquals("/soapenv:Envelope/soapenv:Header/foo:foobar", xpath);
142         assertEquals(WSConstants.AES_128, wsDataRef.getAlgorithm());
143         QName expectedQName = new QName("urn:foo.bar", "foobar");
144         assertEquals(expectedQName, wsDataRef.getName());
145 
146         Element encryptedElement = wsDataRef.getEncryptedElement();
147         assertNotNull(encryptedElement);
148         assertEquals(WSConstants.ENC_NS, encryptedElement.getNamespaceURI());
149     }
150 
151     @Test
152     public void testOptionalSOAPHeaderPresent() throws Exception {
153         Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
154         WSSecHeader secHeader = new WSSecHeader(doc);
155         secHeader.insertSecurityHeader();
156 
157         WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
158         encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
159         encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
160 
161         WSEncryptionPart encP =
162             new WSEncryptionPart(
163                 "foobar",
164                 "urn:foo.bar",
165                 "");
166         encP.setRequired(false);
167         encrypt.getParts().add(encP);
168         String soapNamespace = WSSecurityUtil.getSOAPNamespace(doc.getDocumentElement());
169         encP =
170             new WSEncryptionPart(
171                 WSConstants.ELEM_BODY,
172                 soapNamespace,
173                 "Content"
174             );
175         encrypt.getParts().add(encP);
176 
177         KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
178         SecretKey symmetricKey = keyGen.generateKey();
179         Document encryptedDoc = encrypt.build(crypto, symmetricKey);
180 
181         if (LOG.isDebugEnabled()) {
182             String outputString =
183                 XMLUtils.prettyDocumentToString(encryptedDoc);
184             LOG.debug(outputString);
185         }
186 
187         verify(encryptedDoc);
188     }
189 
190     @Test
191     public void testOptionalSOAPHeaderNotPresent() throws Exception {
192         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
193         WSSecHeader secHeader = new WSSecHeader(doc);
194         secHeader.insertSecurityHeader();
195 
196         WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
197         encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
198         encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
199 
200         WSEncryptionPart encP =
201             new WSEncryptionPart(
202                 "foobar",
203                 "urn:foo.bar",
204                 "");
205         encP.setRequired(false);
206         encrypt.getParts().add(encP);
207         String soapNamespace = WSSecurityUtil.getSOAPNamespace(doc.getDocumentElement());
208         encP =
209             new WSEncryptionPart(
210                 WSConstants.ELEM_BODY,
211                 soapNamespace,
212                 "Content"
213             );
214         encrypt.getParts().add(encP);
215 
216         KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
217         SecretKey symmetricKey = keyGen.generateKey();
218         Document encryptedDoc = encrypt.build(crypto, symmetricKey);
219 
220         if (LOG.isDebugEnabled()) {
221             String outputString =
222                 XMLUtils.prettyDocumentToString(encryptedDoc);
223             LOG.debug(outputString);
224         }
225 
226         verify(encryptedDoc);
227     }
228 
229     @Test
230     public void testRequiredSOAPHeaderNotPresent() throws Exception {
231         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
232         WSSecHeader secHeader = new WSSecHeader(doc);
233         secHeader.insertSecurityHeader();
234 
235         WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
236         encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
237         encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
238 
239         WSEncryptionPart encP =
240             new WSEncryptionPart(
241                 "foobar",
242                 "urn:foo.bar",
243                 "");
244         encrypt.getParts().add(encP);
245         String soapNamespace = WSSecurityUtil.getSOAPNamespace(doc.getDocumentElement());
246         encP =
247             new WSEncryptionPart(
248                 WSConstants.ELEM_BODY,
249                 soapNamespace,
250                 "Content"
251             );
252         encrypt.getParts().add(encP);
253 
254         KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
255         SecretKey symmetricKey = keyGen.generateKey();
256         try {
257             encrypt.build(crypto, symmetricKey);
258             fail("Failure expected on not encrypting a required element");
259         } catch (WSSecurityException ex) {
260             assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
261         }
262     }
263 
264 
265     /**
266      * Test encrypting a custom SOAP header using wsse11:EncryptedHeader
267      */
268     @SuppressWarnings("unchecked")
269     @Test
270     public void testSOAPEncryptedHeader() throws Exception {
271         Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
272         WSSecHeader secHeader = new WSSecHeader(doc);
273         secHeader.insertSecurityHeader();
274 
275         WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
276         encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
277         encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
278 
279         WSEncryptionPart encP =
280             new WSEncryptionPart(
281                 "foobar",
282                 "urn:foo.bar",
283                 "Header");
284         encrypt.getParts().add(encP);
285 
286         KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
287         SecretKey symmetricKey = keyGen.generateKey();
288         Document encryptedDoc = encrypt.build(crypto, symmetricKey);
289 
290         String outputString =
291             XMLUtils.prettyDocumentToString(encryptedDoc);
292         if (LOG.isDebugEnabled()) {
293             LOG.debug(outputString);
294         }
295         assertTrue(outputString.contains("wsse11:EncryptedHeader"));
296         assertFalse(outputString.contains("foo:foobar"));
297 
298         WSHandlerResult results = verify(encryptedDoc);
299 
300         WSSecurityEngineResult actionResult =
301                 results.getActionResults().get(WSConstants.ENCR).get(0);
302         assertNotNull(actionResult);
303         assertFalse(actionResult.isEmpty());
304         final List<WSDataRef> refs =
305             (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
306 
307         assertEquals(WSConstants.KEYTRANSPORT_RSAOAEP,
308                 actionResult.get(WSSecurityEngineResult.TAG_ENCRYPTED_KEY_TRANSPORT_METHOD));
309 
310         WSDataRef wsDataRef = refs.get(0);
311         String xpath = wsDataRef.getXpath();
312         assertEquals("/soapenv:Envelope/soapenv:Header/foo:foobar", xpath);
313     }
314 
315     /**
316      * Test encrypting a custom SOAP header using wsse11:EncryptedHeader
317      */
318     @SuppressWarnings("unchecked")
319     @Test
320     public void testSOAPEncryptedHeaderWithAttributes() throws Exception {
321         Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
322         WSSecHeader secHeader = new WSSecHeader(doc);
323         secHeader.insertSecurityHeader();
324 
325         WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
326         encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
327         encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
328 
329         WSEncryptionPart encP =
330             new WSEncryptionPart(
331                 "with-attributes",
332                 "urn:foo.bar",
333                 "Header");
334         encrypt.getParts().add(encP);
335 
336         KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
337         SecretKey symmetricKey = keyGen.generateKey();
338         Document encryptedDoc = encrypt.build(crypto, symmetricKey);
339 
340         String outputString =
341             XMLUtils.prettyDocumentToString(encryptedDoc);
342         if (LOG.isDebugEnabled()) {
343             LOG.debug(outputString);
344         }
345         assertTrue(outputString.contains("wsse11:EncryptedHeader"));
346         assertFalse(outputString.contains("foo:with-attributes"));
347 
348         WSHandlerResult results = verify(encryptedDoc);
349 
350         WSSecurityEngineResult actionResult =
351             results.getActionResults().get(WSConstants.ENCR).get(0);
352         assertNotNull(actionResult);
353         assertFalse(actionResult.isEmpty());
354         final List<WSDataRef> refs =
355             (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
356 
357         assertEquals(WSConstants.KEYTRANSPORT_RSAOAEP,
358             actionResult.get(WSSecurityEngineResult.TAG_ENCRYPTED_KEY_TRANSPORT_METHOD));
359 
360         WSDataRef wsDataRef = refs.get(0);
361         String xpath = wsDataRef.getXpath();
362         assertEquals("/soapenv:Envelope/soapenv:Header/foo:with-attributes", xpath);
363     }
364 
365     /**
366      * Test encrypting a custom SOAP header with a bad localname
367      */
368     @Test
369     public void testBadLocalname() throws Exception {
370         Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
371         WSSecHeader secHeader = new WSSecHeader(doc);
372         secHeader.insertSecurityHeader();
373 
374         WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
375         encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
376         encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
377 
378         WSEncryptionPart encP =
379             new WSEncryptionPart(
380                 "foobar2",
381                 "urn:foo.bar",
382                 "");
383         encrypt.getParts().add(encP);
384 
385         KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
386         SecretKey symmetricKey = keyGen.generateKey();
387         try {
388             encrypt.build(crypto, symmetricKey);
389             fail("Failure expected on a bad localname");
390         } catch (WSSecurityException ex) {
391             assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
392         }
393     }
394 
395 
396     /**
397      * Test encrypting a custom SOAP header with a bad namespace
398      */
399     @Test
400     public void testBadNamespace() throws Exception {
401         Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
402         WSSecHeader secHeader = new WSSecHeader(doc);
403         secHeader.insertSecurityHeader();
404 
405         WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
406         encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
407         encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
408 
409         WSEncryptionPart encP =
410             new WSEncryptionPart(
411                 "foobar",
412                 "urn:foo.bar2",
413                 "");
414         encrypt.getParts().add(encP);
415 
416         KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
417         SecretKey symmetricKey = keyGen.generateKey();
418         try {
419             encrypt.build(crypto, symmetricKey);
420             fail("Failure expected on a bad namespace");
421         } catch (WSSecurityException ex) {
422             assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
423         }
424     }
425 
426 
427     /**
428      * Test encrypting a custom SOAP header and the SOAP body
429      */
430     @Test
431     public void testSOAPHeaderAndBody() throws Exception {
432         Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
433         SOAPConstants soapConstants =
434             WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
435         WSSecHeader secHeader = new WSSecHeader(doc);
436         secHeader.insertSecurityHeader();
437 
438         WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
439         encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
440         encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
441 
442 
443         WSEncryptionPart encP =
444             new WSEncryptionPart(
445                 soapConstants.getBodyQName().getLocalPart(),    // define the body
446                 soapConstants.getEnvelopeURI(),
447                 "");
448         encrypt.getParts().add(encP);
449         WSEncryptionPart encP2 =
450             new WSEncryptionPart(
451                 "foobar",
452                 "urn:foo.bar",
453                 "");
454         encrypt.getParts().add(encP2);
455 
456         KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
457         SecretKey symmetricKey = keyGen.generateKey();
458         Document encryptedDoc = encrypt.build(crypto, symmetricKey);
459 
460         if (LOG.isDebugEnabled()) {
461             String outputString =
462                 XMLUtils.prettyDocumentToString(encryptedDoc);
463             LOG.debug(outputString);
464         }
465 
466         WSHandlerResult results = verify(encryptedDoc);
467 
468         QName fooName = new QName("urn:foo.bar", "foobar");
469         QName bodyName = new QName(soapConstants.getEnvelopeURI(), "Body");
470         QName headerName = new QName(soapConstants.getEnvelopeURI(), "Header");
471 
472         WSSecurityEngineResult actionResult =
473             results.getActionResults().get(WSConstants.ENCR).get(0);
474         assertNotNull(actionResult);
475         assertFalse(actionResult.isEmpty());
476 
477         @SuppressWarnings("unchecked")
478         final List<WSDataRef> refs =
479             (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
480         assertTrue(refs != null && !refs.isEmpty());
481 
482         boolean foundFoo = false;
483         boolean foundBody = false;
484         boolean foundHeader = false;
485         for (WSDataRef ref : refs) {
486             if (fooName.equals(ref.getName())) {
487                 foundFoo = true;
488             } else if (bodyName.equals(ref.getName())) {
489                 foundBody = true;
490             } else if (headerName.equals(ref.getName())) {
491                 foundHeader = true;
492             }
493         }
494         assertTrue(foundFoo && foundBody);
495         assertFalse(foundHeader);
496     }
497 
498 
499     /**
500      * Test getting a DOM Element from WSEncryptionPart directly
501      */
502     @Test
503     public void testEncryptionPartDOMElement() throws Exception {
504         Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
505         SOAPConstants soapConstants =
506             WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
507         WSSecHeader secHeader = new WSSecHeader(doc);
508         secHeader.insertSecurityHeader();
509 
510         WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
511         encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
512         encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
513 
514         // Give wrong names to make sure it's picking up the element
515         WSEncryptionPart encP =
516             new WSEncryptionPart(
517                 "Incorrect Localname",
518                 "Incorrect N/S",
519                 "");
520         Element bodyElement = WSSecurityUtil.findBodyElement(doc);
521         assertTrue(bodyElement != null && "Body".equals(bodyElement.getLocalName()));
522         encP.setElement(bodyElement);
523         encrypt.getParts().add(encP);
524 
525         KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
526         SecretKey symmetricKey = keyGen.generateKey();
527         Document encryptedDoc = encrypt.build(crypto, symmetricKey);
528 
529         String outputString =
530             XMLUtils.prettyDocumentToString(encryptedDoc);
531         if (LOG.isDebugEnabled()) {
532             LOG.debug(outputString);
533         }
534         assertTrue(!outputString.contains("testMethod"));
535         WSHandlerResult results = verify(encryptedDoc);
536 
537         WSSecurityEngineResult actionResult =
538             results.getActionResults().get(WSConstants.ENCR).get(0);
539         assertNotNull(actionResult);
540         assertFalse(actionResult.isEmpty());
541         @SuppressWarnings("unchecked")
542         final List<WSDataRef> refs =
543             (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
544 
545         WSDataRef wsDataRef = refs.get(0);
546         QName bodyName = new QName(soapConstants.getEnvelopeURI(), "Body");
547         assertEquals(bodyName, wsDataRef.getName());
548     }
549 
550     /**
551      * Test encrypting two SOAP Body elements with the same QName.
552      */
553     @Test
554     public void testMultipleElements() throws Exception {
555         Document doc = SOAPUtil.toSOAPPart(SOAPMSG_MULTIPLE);
556         WSSecHeader secHeader = new WSSecHeader(doc);
557         secHeader.insertSecurityHeader();
558 
559         WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
560         encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
561         encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
562 
563         WSEncryptionPart encP =
564             new WSEncryptionPart(
565                 "testMethod",
566                 "http://axis/service/security/test6/LogTestService8",
567                 "");
568         encrypt.getParts().add(encP);
569 
570         KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
571         SecretKey symmetricKey = keyGen.generateKey();
572         Document encryptedDoc = encrypt.build(crypto, symmetricKey);
573 
574         String outputString =
575             XMLUtils.prettyDocumentToString(encryptedDoc);
576         if (LOG.isDebugEnabled()) {
577             LOG.debug(outputString);
578         }
579         assertFalse(outputString.contains("testMethod"));
580 
581         verify(encryptedDoc);
582 
583         outputString =
584             XMLUtils.prettyDocumentToString(encryptedDoc);
585         assertTrue(outputString.contains("asf1"));
586         assertTrue(outputString.contains("asf2"));
587     }
588 
589 
590     /**
591      * Verifies the soap envelope
592      * <p/>
593      *
594      * @param doc
595      * @throws Exception Thrown when there is a problem in verification
596      */
597     private WSHandlerResult verify(Document doc) throws Exception {
598         WSHandlerResult results =
599             secEngine.processSecurityHeader(doc, null, callbackHandler, null, crypto);
600         if (LOG.isDebugEnabled()) {
601             LOG.debug("Verified and decrypted message:");
602             String outputString =
603                 XMLUtils.prettyDocumentToString(doc);
604             LOG.debug(outputString);
605         }
606         return results;
607     }
608 
609 }