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 javax.crypto.KeyGenerator;
23  import javax.crypto.SecretKey;
24  import javax.security.auth.callback.CallbackHandler;
25  
26  import org.apache.wss4j.common.util.SOAPUtil;
27  import org.apache.wss4j.dom.WSConstants;
28  import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
29  
30  import org.apache.wss4j.dom.engine.WSSConfig;
31  import org.apache.wss4j.dom.engine.WSSecurityEngine;
32  import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
33  import org.apache.wss4j.dom.handler.WSHandlerResult;
34  import org.apache.wss4j.common.WSEncryptionPart;
35  import org.apache.wss4j.common.crypto.Crypto;
36  import org.apache.wss4j.common.crypto.CryptoFactory;
37  import org.apache.wss4j.common.util.KeyUtils;
38  import org.apache.wss4j.common.util.XMLUtils;
39  import org.apache.wss4j.dom.util.WSSecurityUtil;
40  
41  import org.junit.jupiter.api.Test;
42  import org.w3c.dom.Document;
43  import org.w3c.dom.Element;
44  
45  import static org.junit.jupiter.api.Assertions.assertFalse;
46  import static org.junit.jupiter.api.Assertions.assertNotNull;
47  
48  /**
49   * This test encrypts a Timestamp and the SOAP Body, and appends the ReferenceList Element after the
50   * EncryptedData Element that is the Timestamp. When processing, the EncryptedData Element gets decrypted,
51   * and then the ReferenceListProcessor must check to see whether the Data Reference pointing to the
52   * encrypted Timestamp needs to be decrypted or not.
53   */
54  public class EncryptedDataInHeaderTest {
55      private static final org.slf4j.Logger LOG =
56          org.slf4j.LoggerFactory.getLogger(EncryptedDataInHeaderTest.class);
57  
58      private WSSecurityEngine secEngine = new WSSecurityEngine();
59      private CallbackHandler callbackHandler = new KeystoreCallbackHandler();
60      private Crypto crypto;
61  
62      public EncryptedDataInHeaderTest() throws Exception {
63          crypto = CryptoFactory.getInstance();
64          WSSConfig.init();
65      }
66  
67      @Test
68      public void testEncryptedDataInHeader() throws Exception {
69          Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
70          WSSecHeader secHeader = new WSSecHeader(doc);
71          secHeader.insertSecurityHeader();
72  
73          WSSecTimestamp timestamp = new WSSecTimestamp(secHeader);
74          timestamp.setTimeToLive(300);
75          timestamp.build();
76  
77          WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
78          encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
79          encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
80  
81          // Encrypt the Timestamp and SOAP Body
82          WSEncryptionPart encP =
83              new WSEncryptionPart(
84                  "Timestamp", WSConstants.WSU_NS, "");
85          encrypt.getParts().add(encP);
86          String soapNamespace = WSSecurityUtil.getSOAPNamespace(doc.getDocumentElement());
87          encP =
88              new WSEncryptionPart(
89                  WSConstants.ELEM_BODY, soapNamespace, "Content"
90              );
91          encrypt.getParts().add(encP);
92  
93          KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
94          SecretKey symmetricKey = keyGen.generateKey();
95          encrypt.prepare(crypto, symmetricKey);
96          encrypt.prependToHeader();
97  
98          // Append Reference List to security header
99          Element refs = encrypt.encrypt(symmetricKey);
100         secHeader.getSecurityHeaderElement().appendChild(refs);
101 
102         if (LOG.isDebugEnabled()) {
103             String outputString =
104                 XMLUtils.prettyDocumentToString(doc);
105             LOG.debug(outputString);
106         }
107 
108         WSHandlerResult results = verify(doc);
109         WSSecurityEngineResult actionResult =
110             results.getActionResults().get(WSConstants.ENCR).get(0);
111         assertNotNull(actionResult);
112         assertFalse(actionResult.isEmpty());
113     }
114 
115 
116     /**
117      * Verifies the soap envelope
118      * <p/>
119      *
120      * @param doc
121      * @throws Exception Thrown when there is a problem in verification
122      */
123     private WSHandlerResult verify(Document doc) throws Exception {
124         WSHandlerResult results =
125             secEngine.processSecurityHeader(doc, null, callbackHandler, null, crypto);
126         if (LOG.isDebugEnabled()) {
127             LOG.debug("Verified and decrypted message:");
128             String outputString =
129                 XMLUtils.prettyDocumentToString(doc);
130             LOG.debug(outputString);
131         }
132         return results;
133     }
134 
135 }