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 javax.crypto.KeyGenerator;
23 import javax.crypto.SecretKey;
24 import javax.security.auth.callback.CallbackHandler;
25
26 import org.apache.wss4j.common.bsp.BSPRule;
27 import org.apache.wss4j.common.util.SOAPUtil;
28 import org.apache.wss4j.dom.WSConstants;
29 import org.apache.wss4j.dom.WSDataRef;
30 import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
31
32 import org.apache.wss4j.dom.engine.WSSConfig;
33 import org.apache.wss4j.dom.engine.WSSecurityEngine;
34 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
35 import org.apache.wss4j.common.crypto.Crypto;
36 import org.apache.wss4j.common.crypto.CryptoFactory;
37 import org.apache.wss4j.common.util.DOM2Writer;
38 import org.apache.wss4j.common.util.KeyUtils;
39 import org.apache.wss4j.common.util.XMLUtils;
40 import org.apache.wss4j.dom.handler.RequestData;
41 import org.apache.wss4j.dom.handler.WSHandlerResult;
42
43 import org.junit.jupiter.api.BeforeEach;
44 import org.junit.jupiter.api.Test;
45 import org.w3c.dom.Document;
46
47 import java.util.ArrayList;
48 import java.util.List;
49
50 import static org.junit.jupiter.api.Assertions.assertEquals;
51 import static org.junit.jupiter.api.Assertions.assertFalse;
52 import static org.junit.jupiter.api.Assertions.assertNotNull;
53 import static org.junit.jupiter.api.Assertions.assertTrue;
54 import static org.junit.jupiter.api.Assumptions.assumeFalse;
55
56
57
58
59
60 public class EncryptionGCMTest {
61 private static final org.slf4j.Logger LOG =
62 org.slf4j.LoggerFactory.getLogger(EncryptionGCMTest.class);
63 private static final javax.xml.namespace.QName SOAP_BODY =
64 new javax.xml.namespace.QName(
65 WSConstants.URI_SOAP11_ENV,
66 "Body"
67 );
68
69 private WSSecurityEngine secEngine = new WSSecurityEngine();
70 private CallbackHandler keystoreCallbackHandler = new KeystoreCallbackHandler();
71 private Crypto crypto;
72
73 private boolean isIBMJdK = System.getProperty("java.vendor").contains("IBM");
74
75 public EncryptionGCMTest() throws Exception {
76 crypto = CryptoFactory.getInstance("wss40.properties");
77 }
78
79
80
81
82
83
84 @BeforeEach
85 public void setUp() throws Exception {
86 secEngine.setWssConfig(WSSConfig.getNewInstance());
87 }
88
89 @Test
90 public void testAES128GCM() throws Exception {
91 assumeFalse(isIBMJdK);
92
93 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
94 WSSecHeader secHeader = new WSSecHeader(doc);
95 secHeader.insertSecurityHeader();
96
97 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
98 builder.setUserInfo("wss40");
99 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
100 builder.setSymmetricEncAlgorithm(WSConstants.AES_128_GCM);
101
102 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128_GCM);
103 SecretKey symmetricKey = keyGen.generateKey();
104 Document encryptedDoc = builder.build(crypto, symmetricKey);
105
106 String outputString =
107 XMLUtils.prettyDocumentToString(encryptedDoc);
108 if (LOG.isDebugEnabled()) {
109 LOG.debug("Encrypted message:");
110 LOG.debug(outputString);
111 }
112 assertFalse(outputString.contains("counter_port_type"));
113 verify(encryptedDoc, keystoreCallbackHandler, SOAP_BODY);
114 }
115
116 @Test
117 public void testAES256GCM() throws Exception {
118 assumeFalse(isIBMJdK);
119
120 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
121 WSSecHeader secHeader = new WSSecHeader(doc);
122 secHeader.insertSecurityHeader();
123
124 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
125 builder.setUserInfo("wss40");
126 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
127 builder.setSymmetricEncAlgorithm(WSConstants.AES_256_GCM);
128
129 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_256_GCM);
130 SecretKey symmetricKey = keyGen.generateKey();
131 Document encryptedDoc = builder.build(crypto, symmetricKey);
132
133 String outputString =
134 XMLUtils.prettyDocumentToString(encryptedDoc);
135 if (LOG.isDebugEnabled()) {
136 LOG.debug("Encrypted message:");
137 LOG.debug(outputString);
138 }
139 assertFalse(outputString.contains("counter_port_type"));
140 verify(encryptedDoc, keystoreCallbackHandler, SOAP_BODY);
141 }
142
143 @Test
144 public void testAES192GCM_RSAOAEP_SHA256_MGFSHA256() throws Exception {
145 assumeFalse(isIBMJdK);
146
147 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
148 WSSecHeader secHeader = new WSSecHeader(doc);
149 secHeader.insertSecurityHeader();
150
151 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
152 builder.setUserInfo("wss40");
153 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
154 builder.setSymmetricEncAlgorithm(WSConstants.AES_192_GCM);
155 builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSAOAEP_XENC11);
156 builder.setDigestAlgorithm(WSConstants.SHA256);
157 builder.setMGFAlgorithm(WSConstants.MGF_SHA256);
158
159 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_192_GCM);
160 SecretKey symmetricKey = keyGen.generateKey();
161 Document encryptedDoc = builder.build(crypto, symmetricKey);
162
163 String outputString =
164 XMLUtils.prettyDocumentToString(encryptedDoc);
165 if (LOG.isDebugEnabled()) {
166 LOG.debug("Encrypted message:");
167 LOG.debug(outputString);
168 }
169 assertTrue(outputString.indexOf("http://www.w3.org/2009/xmlenc11#rsa-oaep") > 0);
170 assertTrue(outputString.indexOf("http://www.w3.org/2001/04/xmlenc#sha256") > 0);
171 assertTrue(outputString.indexOf("http://www.w3.org/2009/xmlenc11#aes192-gcm") > 0);
172 assertTrue(outputString.indexOf("http://www.w3.org/2009/xmlenc11#mgf1sha256") > 0);
173 assertFalse(outputString.contains("counter_port_type"));
174 verify(encryptedDoc, keystoreCallbackHandler, SOAP_BODY);
175 }
176
177
178
179
180
181
182
183 @SuppressWarnings("unchecked")
184 private void verify(
185 Document doc,
186 CallbackHandler handler,
187 javax.xml.namespace.QName expectedEncryptedElement
188 ) throws Exception {
189 RequestData requestData = new RequestData();
190 List<BSPRule> bspRules = new ArrayList<>();
191 bspRules.add(BSPRule.R5621);
192 bspRules.add(BSPRule.R5620);
193 requestData.setIgnoredBSPRules(bspRules);
194 requestData.setCallbackHandler(handler);
195 requestData.setDecCrypto(crypto);
196 final WSHandlerResult results = secEngine.processSecurityHeader(doc, requestData);
197 String outputString =
198 XMLUtils.prettyDocumentToString(doc);
199 if (LOG.isDebugEnabled()) {
200 LOG.debug(outputString);
201 }
202 assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
203
204
205
206
207
208 boolean encrypted = false;
209 for (WSSecurityEngineResult result : results.getResults()) {
210 final Integer action = (Integer) result.get(WSSecurityEngineResult.TAG_ACTION);
211 assertNotNull(action);
212 if ((action & WSConstants.ENCR) != 0) {
213 final List<WSDataRef> refs =
214 (List<WSDataRef>) result.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
215 assertNotNull(refs);
216 encrypted = true;
217 for (WSDataRef ref : refs) {
218 assertNotNull(ref.getName());
219 assertEquals(
220 expectedEncryptedElement,
221 ref.getName()
222 );
223 assertNotNull(ref.getProtectedElement());
224 if (LOG.isDebugEnabled()) {
225 LOG.debug("WSDataRef element: ");
226 LOG.debug(
227 DOM2Writer.nodeToString(ref.getProtectedElement())
228 );
229 }
230 }
231 }
232 }
233 assertTrue(encrypted);
234 }
235
236 }