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
25 import org.apache.wss4j.common.crypto.AlgorithmSuite;
26 import org.apache.wss4j.common.crypto.Crypto;
27 import org.apache.wss4j.common.crypto.CryptoFactory;
28 import org.apache.wss4j.common.ext.WSSecurityException;
29 import org.apache.wss4j.common.util.KeyUtils;
30 import org.apache.wss4j.common.util.SOAPUtil;
31 import org.apache.wss4j.common.util.XMLUtils;
32 import org.apache.wss4j.dom.WSConstants;
33 import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
34 import org.apache.wss4j.dom.common.SecretKeyCallbackHandler;
35
36 import org.apache.wss4j.dom.engine.WSSConfig;
37 import org.apache.wss4j.dom.engine.WSSecurityEngine;
38 import org.apache.wss4j.dom.handler.RequestData;
39 import org.apache.wss4j.dom.handler.WSHandlerResult;
40 import org.apache.wss4j.dom.util.WSSecurityUtil;
41
42 import org.junit.jupiter.api.Test;
43 import org.w3c.dom.Document;
44 import org.w3c.dom.Element;
45
46 import static org.junit.jupiter.api.Assertions.assertTrue;
47 import static org.junit.jupiter.api.Assertions.fail;
48
49
50
51
52
53 public class EncryptionAlgorithmSuiteTest {
54 private static final org.slf4j.Logger LOG =
55 org.slf4j.LoggerFactory.getLogger(EncryptionAlgorithmSuiteTest.class);
56
57 private Crypto crypto;
58
59 public EncryptionAlgorithmSuiteTest() throws Exception {
60 WSSConfig.init();
61 crypto = CryptoFactory.getInstance("wss40.properties");
62 }
63
64 @Test
65 public void testEncryption() throws Exception {
66 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
67 WSSecHeader secHeader = new WSSecHeader(doc);
68 secHeader.insertSecurityHeader();
69
70 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
71 builder.setUserInfo("wss40");
72 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
73 builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
74
75 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.TRIPLE_DES);
76 SecretKey symmetricKey = keyGen.generateKey();
77 Document encryptedDoc = builder.build(crypto, symmetricKey);
78
79 if (LOG.isDebugEnabled()) {
80 String outputString =
81 XMLUtils.prettyDocumentToString(encryptedDoc);
82 LOG.debug(outputString);
83 }
84
85 Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
86 AlgorithmSuite algorithmSuite = createAlgorithmSuite();
87
88 verify(securityHeader, algorithmSuite, crypto);
89
90 algorithmSuite.setMinimumAsymmetricKeyLength(1024);
91
92 try {
93 verify(securityHeader, algorithmSuite, crypto);
94 fail("Expected failure as 512-bit keys are not allowed");
95 } catch (WSSecurityException ex) {
96 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
97 }
98 }
99
100 @Test
101 public void testEncryptionKeyTransportRSA15() throws Exception {
102
103 Crypto wssCrypto = CryptoFactory.getInstance("wss40.properties");
104
105 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
106 WSSecHeader secHeader = new WSSecHeader(doc);
107 secHeader.insertSecurityHeader();
108
109 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
110 builder.setUserInfo("wss40");
111 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
112 builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
113 builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSA15);
114
115 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.TRIPLE_DES);
116 SecretKey symmetricKey = keyGen.generateKey();
117 Document encryptedDoc = builder.build(crypto, symmetricKey);
118
119 if (LOG.isDebugEnabled()) {
120 String outputString =
121 XMLUtils.prettyDocumentToString(encryptedDoc);
122 LOG.debug(outputString);
123 }
124
125 Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
126 AlgorithmSuite algorithmSuite = createAlgorithmSuite();
127
128 try {
129 verify(securityHeader, algorithmSuite, wssCrypto);
130 fail("Expected failure as RSA 15 is not allowed");
131 } catch (WSSecurityException ex) {
132 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
133 }
134
135 algorithmSuite.addKeyWrapAlgorithm(WSConstants.KEYTRANSPORT_RSA15);
136 verify(securityHeader, algorithmSuite, wssCrypto);
137 }
138
139 @Test
140 public void testEncryptionKeyTransportRSA15NoAlgorithmSuite() throws Exception {
141
142 Crypto wssCrypto = CryptoFactory.getInstance("wss40.properties");
143
144 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
145 WSSecHeader secHeader = new WSSecHeader(doc);
146 secHeader.insertSecurityHeader();
147
148 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
149 builder.setUserInfo("wss40");
150 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
151 builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
152 builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSA15);
153
154 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.TRIPLE_DES);
155 SecretKey symmetricKey = keyGen.generateKey();
156 Document encryptedDoc = builder.build(crypto, symmetricKey);
157
158 if (LOG.isDebugEnabled()) {
159 String outputString =
160 XMLUtils.prettyDocumentToString(encryptedDoc);
161 LOG.debug(outputString);
162 }
163
164 Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
165
166 try {
167 verify(securityHeader, null, wssCrypto);
168 fail("Expected failure as RSA 15 is not allowed");
169 } catch (WSSecurityException ex) {
170 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
171 }
172
173
174 WSSecurityEngine secEngine = new WSSecurityEngine();
175 RequestData data = new RequestData();
176 data.setDecCrypto(wssCrypto);
177 data.setAllowRSA15KeyTransportAlgorithm(true);
178
179 data.setCallbackHandler(new KeystoreCallbackHandler());
180
181 secEngine.processSecurityHeader(securityHeader, data);
182 }
183
184 @Test
185 public void testEncryptionMethodAES128() throws Exception {
186
187 Crypto wssCrypto = CryptoFactory.getInstance("wss40.properties");
188
189 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
190 WSSecHeader secHeader = new WSSecHeader(doc);
191 secHeader.insertSecurityHeader();
192
193 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
194 builder.setUserInfo("wss40");
195 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
196 builder.setSymmetricEncAlgorithm(WSConstants.AES_128);
197
198 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
199 SecretKey symmetricKey = keyGen.generateKey();
200 Document encryptedDoc = builder.build(crypto, symmetricKey);
201
202 if (LOG.isDebugEnabled()) {
203 String outputString =
204 XMLUtils.prettyDocumentToString(encryptedDoc);
205 LOG.debug(outputString);
206 }
207
208 Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
209 AlgorithmSuite algorithmSuite = createAlgorithmSuite();
210
211 try {
212 verify(securityHeader, algorithmSuite, wssCrypto);
213 fail("Expected failure as AES 128 is not allowed");
214 } catch (WSSecurityException ex) {
215 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
216 }
217
218 algorithmSuite.addEncryptionMethod(WSConstants.AES_128);
219 verify(securityHeader, algorithmSuite, wssCrypto);
220 }
221
222 @Test
223 public void testSymmetricEncryption() throws Exception {
224
225 KeyGenerator keyGen = KeyGenerator.getInstance("AES");
226 keyGen.init(128);
227 SecretKey key = keyGen.generateKey();
228 byte[] keyData = key.getEncoded();
229
230 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
231 WSSecHeader secHeader = new WSSecHeader(doc);
232 secHeader.insertSecurityHeader();
233
234 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
235 builder.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
236 builder.setEncryptSymmKey(false);
237
238 Document encryptedDoc = builder.build(crypto, key);
239
240 if (LOG.isDebugEnabled()) {
241 String outputString =
242 XMLUtils.prettyDocumentToString(encryptedDoc);
243 LOG.debug(outputString);
244 }
245
246 byte[] encodedBytes = KeyUtils.generateDigest(keyData);
247 String identifier = org.apache.xml.security.utils.XMLUtils.encodeToString(encodedBytes);
248 SecretKeyCallbackHandler secretKeyCallbackHandler = new SecretKeyCallbackHandler();
249 secretKeyCallbackHandler.addSecretKey(identifier, keyData);
250
251 Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
252 AlgorithmSuite algorithmSuite = createAlgorithmSuite();
253
254 WSSecurityEngine secEngine = new WSSecurityEngine();
255 RequestData data = new RequestData();
256 data.setDecCrypto(crypto);
257 data.setCallbackHandler(secretKeyCallbackHandler);
258
259 data.setAlgorithmSuite(algorithmSuite);
260
261 algorithmSuite.addEncryptionMethod(WSConstants.AES_128);
262 secEngine.processSecurityHeader(securityHeader, data);
263
264 algorithmSuite.setMinimumSymmetricKeyLength(256);
265 try {
266 secEngine.processSecurityHeader(securityHeader, data);
267 fail("Expected failure as a 128 bit key is not allowed");
268 } catch (WSSecurityException ex) {
269 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
270 }
271
272 algorithmSuite.setMinimumSymmetricKeyLength(64);
273 algorithmSuite.setMaximumSymmetricKeyLength(120);
274 try {
275 secEngine.processSecurityHeader(securityHeader, data);
276 fail("Expected failure as a 128 bit key is not allowed");
277 } catch (WSSecurityException ex) {
278 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
279 }
280 }
281
282
283 private AlgorithmSuite createAlgorithmSuite() {
284 AlgorithmSuite algorithmSuite = new AlgorithmSuite();
285 algorithmSuite.setMinimumAsymmetricKeyLength(512);
286 algorithmSuite.addKeyWrapAlgorithm(WSConstants.KEYTRANSPORT_RSAOAEP);
287 algorithmSuite.addEncryptionMethod(WSConstants.TRIPLE_DES);
288
289 return algorithmSuite;
290 }
291
292 private WSHandlerResult verify(
293 Element securityHeader, AlgorithmSuite algorithmSuite, Crypto decCrypto
294 ) throws Exception {
295 WSSecurityEngine secEngine = new WSSecurityEngine();
296 RequestData data = new RequestData();
297 data.setDecCrypto(decCrypto);
298
299 data.setAlgorithmSuite(algorithmSuite);
300
301 data.setCallbackHandler(new KeystoreCallbackHandler());
302
303 return secEngine.processSecurityHeader(securityHeader, data);
304 }
305
306 }