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 java.security.Security;
23 import java.security.cert.X509Certificate;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.UUID;
27
28 import javax.crypto.KeyGenerator;
29 import javax.crypto.SecretKey;
30 import javax.security.auth.callback.CallbackHandler;
31
32 import org.apache.wss4j.common.WSEncryptionPart;
33 import org.apache.wss4j.common.WSS4JConstants;
34 import org.apache.wss4j.common.bsp.BSPRule;
35 import org.apache.wss4j.common.crypto.Crypto;
36 import org.apache.wss4j.common.crypto.CryptoFactory;
37 import org.apache.wss4j.common.crypto.CryptoType;
38 import org.apache.wss4j.common.ext.WSSecurityException;
39 import org.apache.wss4j.common.util.*;
40 import org.apache.wss4j.dom.SOAPConstants;
41 import org.apache.wss4j.dom.WSConstants;
42 import org.apache.wss4j.dom.WSDataRef;
43 import org.apache.wss4j.dom.common.CustomHandler;
44 import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
45 import org.apache.wss4j.dom.common.SecretKeyCallbackHandler;
46
47 import org.apache.wss4j.dom.engine.WSSConfig;
48 import org.apache.wss4j.dom.engine.WSSecurityEngine;
49 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
50 import org.apache.wss4j.dom.handler.HandlerAction;
51 import org.apache.wss4j.dom.handler.RequestData;
52 import org.apache.wss4j.dom.handler.WSHandlerConstants;
53 import org.apache.wss4j.dom.handler.WSHandlerResult;
54 import org.apache.wss4j.dom.str.STRParser.REFERENCE_TYPE;
55 import org.apache.wss4j.dom.util.WSSecurityUtil;
56 import org.apache.xml.security.encryption.params.HKDFParams;
57 import org.apache.xml.security.utils.EncryptionConstants;
58 import org.junit.jupiter.api.AfterEach;
59 import org.junit.jupiter.api.BeforeEach;
60 import org.junit.jupiter.api.Test;
61 import org.junit.jupiter.params.ParameterizedTest;
62 import org.junit.jupiter.params.provider.CsvSource;
63 import org.w3c.dom.Document;
64 import org.w3c.dom.Element;
65
66 import static org.junit.jupiter.api.Assertions.assertEquals;
67 import static org.junit.jupiter.api.Assertions.assertFalse;
68 import static org.junit.jupiter.api.Assertions.assertNotNull;
69 import static org.junit.jupiter.api.Assertions.assertTrue;
70 import static org.junit.jupiter.api.Assertions.fail;
71
72
73
74
75 public class EncryptionTest {
76 private static final org.slf4j.Logger LOG =
77 org.slf4j.LoggerFactory.getLogger(EncryptionTest.class);
78 private static final javax.xml.namespace.QName SOAP_BODY =
79 new javax.xml.namespace.QName(
80 WSConstants.URI_SOAP11_ENV,
81 "Body"
82 );
83
84 private WSSecurityEngine secEngine = new WSSecurityEngine();
85 private CallbackHandler keystoreCallbackHandler = new KeystoreCallbackHandler();
86 private SecretKeyCallbackHandler secretKeyCallbackHandler = new SecretKeyCallbackHandler();
87 private byte[] keyData;
88 private SecretKey key;
89 private Crypto crypto;
90
91 public EncryptionTest() throws Exception {
92 crypto = CryptoFactory.getInstance("wss40.properties");
93 }
94
95
96
97
98
99
100 @BeforeEach
101 public void setUp() throws Exception {
102 KeyGenerator keyGen = KeyGenerator.getInstance("AES");
103 keyGen.init(128);
104 key = keyGen.generateKey();
105 keyData = key.getEncoded();
106 secEngine.setWssConfig(WSSConfig.getNewInstance());
107 }
108
109 @AfterEach
110 public void cleanup() {
111 JDKTestUtils.unregisterAuxiliaryProvider();
112 }
113
114
115
116
117
118
119
120
121
122 @Test
123 public void testEncryptionDecryptionRSA15() throws Exception {
124 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
125 WSSecHeader secHeader = new WSSecHeader(doc);
126 secHeader.insertSecurityHeader();
127
128 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
129 builder.setUserInfo("wss40");
130 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
131 builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
132
133 LOG.info("Before Encryption Triple DES....");
134 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.TRIPLE_DES);
135 SecretKey symmetricKey = keyGen.generateKey();
136 Document encryptedDoc = builder.build(crypto, symmetricKey);
137 LOG.info("After Encryption Triple DES....");
138
139 String outputString =
140 XMLUtils.prettyDocumentToString(encryptedDoc);
141 if (LOG.isDebugEnabled()) {
142 LOG.debug("Encrypted message, RSA-15 keytransport, 3DES:");
143 LOG.debug(outputString);
144 }
145 assertFalse(outputString.contains("counter_port_type"));
146 verify(encryptedDoc, keystoreCallbackHandler, SOAP_BODY);
147 builder.getParts().clear();
148
149
150
151
152
153
154
155 doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
156 secHeader = new WSSecHeader(doc);
157 secHeader.insertSecurityHeader();
158
159 builder = new WSSecEncrypt(secHeader);
160 builder.setUserInfo("wss40");
161 builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
162 builder.setSymmetricEncAlgorithm(WSConstants.AES_128);
163
164 WSEncryptionPart encP =
165 new WSEncryptionPart(
166 "add", "http://ws.apache.org/counter/counter_port_type", "Element"
167 );
168 builder.getParts().add(encP);
169
170 LOG.info("Before Encryption AES 128/RSA-15....");
171 keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
172 symmetricKey = keyGen.generateKey();
173 encryptedDoc = builder.build(crypto, symmetricKey);
174 LOG.info("After Encryption AES 128/RSA-15....");
175 outputString =
176 XMLUtils.prettyDocumentToString(encryptedDoc);
177 if (LOG.isDebugEnabled()) {
178 LOG.debug("Encrypted message, RSA-15 keytransport, AES 128:");
179 LOG.debug(outputString);
180 }
181 assertFalse(outputString.contains("counter_port_type"));
182 WSHandlerResult results = verify(
183 encryptedDoc,
184 keystoreCallbackHandler,
185 new javax.xml.namespace.QName(
186 "http://ws.apache.org/counter/counter_port_type",
187 "add"
188 )
189 );
190
191 WSSecurityEngineResult actionResult =
192 results.getActionResults().get(WSConstants.ENCR).get(0);
193 assertNotNull(actionResult.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE));
194 assertNotNull(actionResult.get(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE));
195 REFERENCE_TYPE referenceType =
196 (REFERENCE_TYPE)actionResult.get(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE);
197 assertTrue(referenceType == REFERENCE_TYPE.ISSUER_SERIAL);
198 }
199
200
201
202
203
204
205
206
207
208 @Test
209 public void testEncryptionDecryptionOAEP() throws Exception {
210 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
211 WSSecHeader secHeader = new WSSecHeader(doc);
212 secHeader.insertSecurityHeader();
213
214 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
215 builder.setUserInfo("wss40");
216 builder.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER);
217 builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSAOAEP);
218
219 LOG.info("Before Encryption Triple DES/RSA-OAEP....");
220 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
221 SecretKey symmetricKey = keyGen.generateKey();
222 Document encryptedDoc = builder.build(crypto, symmetricKey);
223 LOG.info("After Encryption Triple DES/RSA-OAEP....");
224
225 String outputString =
226 XMLUtils.prettyDocumentToString(encryptedDoc);
227 if (LOG.isDebugEnabled()) {
228 LOG.debug("Encrypted message, RSA-OAEP keytransport, 3DES:");
229 LOG.debug(outputString);
230 }
231 assertFalse(outputString.contains("counter_port_type"));
232
233 WSSecurityEngine newEngine = new WSSecurityEngine();
234 WSHandlerResult results =
235 newEngine.processSecurityHeader(encryptedDoc, null, keystoreCallbackHandler, crypto);
236
237 WSSecurityEngineResult actionResult =
238 results.getActionResults().get(WSConstants.ENCR).get(0);
239 assertNotNull(actionResult.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE));
240 assertNotNull(actionResult.get(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE));
241 REFERENCE_TYPE referenceType =
242 (REFERENCE_TYPE)actionResult.get(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE);
243 assertTrue(referenceType == REFERENCE_TYPE.KEY_IDENTIFIER);
244 }
245
246 @Test
247 public void testEncryptionDecryptionPublicKey() throws Exception {
248 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
249 WSSecHeader secHeader = new WSSecHeader(doc);
250 secHeader.insertSecurityHeader();
251
252 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
253 builder.setKeyIdentifierType(WSConstants.KEY_VALUE);
254 builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSAOAEP);
255
256 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
257 cryptoType.setAlias("wss40");
258 X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
259 assertNotNull(certs);
260 builder.setUseThisPublicKey(certs[0].getPublicKey());
261
262 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
263 SecretKey symmetricKey = keyGen.generateKey();
264 Document encryptedDoc = builder.build(crypto, symmetricKey);
265
266 String outputString =
267 XMLUtils.prettyDocumentToString(encryptedDoc);
268 if (LOG.isDebugEnabled()) {
269 LOG.debug(outputString);
270 }
271 assertFalse(outputString.contains("counter_port_type"));
272
273 WSSecurityEngine newEngine = new WSSecurityEngine();
274 WSHandlerResult results =
275 newEngine.processSecurityHeader(encryptedDoc, null, keystoreCallbackHandler, crypto);
276
277 WSSecurityEngineResult actionResult =
278 results.getActionResults().get(WSConstants.ENCR).get(0);
279 assertNotNull(actionResult.get(WSSecurityEngineResult.TAG_PUBLIC_KEY));
280 }
281
282
283
284
285
286
287
288
289
290 @Test
291 public void testEncryptionEncryption() throws Exception {
292 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
293 WSSecHeader secHeader = new WSSecHeader(doc);
294 secHeader.insertSecurityHeader();
295
296 Crypto encCrypto = CryptoFactory.getInstance();
297 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
298 encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");
299 LOG.info("Before Encryption....");
300
301 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
302 SecretKey symmetricKey = keyGen.generateKey();
303 Document encryptedDoc = encrypt.build(encCrypto, symmetricKey);
304
305 if (LOG.isDebugEnabled()) {
306 LOG.debug("After the first encryption:");
307 String outputString =
308 XMLUtils.prettyDocumentToString(encryptedDoc);
309 LOG.debug(outputString);
310 }
311
312 Document encryptedEncryptedDoc = encrypt.build(encCrypto, symmetricKey);
313
314 if (LOG.isDebugEnabled()) {
315 LOG.debug("After the second encryption:");
316 String outputString =
317 XMLUtils.prettyDocumentToString(encryptedEncryptedDoc);
318 LOG.debug(outputString);
319 }
320
321 LOG.info("After Encryption....");
322 verify(encryptedEncryptedDoc, encCrypto, keystoreCallbackHandler);
323 }
324
325
326
327
328
329
330
331
332
333
334
335
336
337 @ParameterizedTest
338 @CsvSource({"xdh, X25519, http://www.w3.org/2021/04/xmldsig-more#x25519, http://www.w3.org/2009/xmlenc11#ConcatKDF",
339 "xdh, X448, http://www.w3.org/2021/04/xmldsig-more#x448, http://www.w3.org/2009/xmlenc11#ConcatKDF",
340 "ec, secp256r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2009/xmlenc11#ConcatKDF",
341 "ec, secp384r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2009/xmlenc11#ConcatKDF",
342 "ec, secp521r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2009/xmlenc11#ConcatKDF",
343 "xdh, X25519, http://www.w3.org/2021/04/xmldsig-more#x25519, http://www.w3.org/2021/04/xmldsig-more#hkdf",
344 "xdh, X448, http://www.w3.org/2021/04/xmldsig-more#x448, http://www.w3.org/2021/04/xmldsig-more#hkdf",
345 "ec, secp256r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2021/04/xmldsig-more#hkdf",
346 "ec, secp384r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2021/04/xmldsig-more#hkdf",
347 "ec, secp521r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2021/04/xmldsig-more#hkdf",
348 })
349 public void testEncryptionDecryptionWithKeyAgreementAndDefaultKDF(String algorithm, String certAlias, String keyAgreementMethod, String kdfAlgorithm) throws Exception {
350 try {
351 if (!JDKTestUtils.isAlgorithmSupportedByJDK(algorithm)) {
352 LOG.info("Add AuxiliaryProvider to execute test with algorithm [{}] and cert alias [{}]", algorithm, certAlias);
353 Security.addProvider(JDKTestUtils.getAuxiliaryProvider());
354 } else if (JDKTestUtils.getJDKVersion() == 11 && algorithm.equals("xdh")) {
355
356
357
358 Security.insertProviderAt(JDKTestUtils.getAuxiliaryProvider(), 1);
359 }
360 Crypto encCrypto = CryptoFactory.getInstance("wss-ecdh.properties");
361
362 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
363 WSSecHeader secHeader = new WSSecHeader(doc);
364 secHeader.insertSecurityHeader();
365
366 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
367 builder.setUserInfo(certAlias);
368 builder.setKeyEncAlgo(WSConstants.KEYWRAP_AES128);
369 builder.setKeyAgreementMethod(keyAgreementMethod);
370 builder.setKeyDerivationMethod(kdfAlgorithm);
371 if (kdfAlgorithm.equalsIgnoreCase(WSS4JConstants.KEYDERIVATION_CONCATKDF)){
372 builder.setDigestAlgorithm(WSS4JConstants.SHA256);
373 }
374 builder.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);
375
376 LOG.info("Before Encryption ...");
377 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128_GCM);
378 SecretKey symmetricKey = keyGen.generateKey();
379
380 Document encryptedDoc = builder.build(encCrypto, symmetricKey);
381 LOG.info("After Encryption ....");
382
383 String outputString =
384 XMLUtils.prettyDocumentToString(encryptedDoc);
385
386 if (LOG.isDebugEnabled()) {
387 LOG.debug("Encrypted message:");
388 LOG.debug(outputString);
389 }
390 assertFalse(outputString.contains("counter_port_type"));
391
392 assertTrue(outputString.contains(EncryptionConstants._TAG_AGREEMENTMETHOD));
393 assertTrue(outputString.contains(WSConstants.KEYWRAP_AES128));
394 assertTrue(outputString.contains(keyAgreementMethod));
395
396 WSSecurityEngine newEngine = new WSSecurityEngine();
397 WSHandlerResult results =
398 newEngine.processSecurityHeader(encryptedDoc, null, keystoreCallbackHandler, encCrypto);
399
400 WSSecurityEngineResult actionResult =
401 results.getActionResults().get(WSConstants.ENCR).get(0);
402 assertNotNull(actionResult);
403 } finally {
404 Security.removeProvider(JDKTestUtils.getAuxiliaryProvider().getName());
405 }
406 }
407
408
409
410
411
412
413
414
415 @ParameterizedTest
416 @CsvSource({
417 "xdh, X25519, http://www.w3.org/2021/04/xmldsig-more#x25519, http://www.w3.org/2001/04/xmlenc#kw-aes128, 128",
418 "xdh, X448, http://www.w3.org/2021/04/xmldsig-more#x448, http://www.w3.org/2001/04/xmlenc#kw-aes128, 128",
419 "ec, secp256r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2001/04/xmlenc#kw-aes128, 128",
420 "ec, secp384r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2001/04/xmlenc#kw-aes128, 128",
421 "ec, secp521r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2001/04/xmlenc#kw-aes128, 128",
422 "xdh, X25519, http://www.w3.org/2021/04/xmldsig-more#x25519, http://www.w3.org/2001/04/xmlenc#kw-aes192, 192",
423 "xdh, X448, http://www.w3.org/2021/04/xmldsig-more#x448, http://www.w3.org/2001/04/xmlenc#kw-aes192, 192",
424 "ec, secp256r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2001/04/xmlenc#kw-aes192, 192",
425 "ec, secp384r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2001/04/xmlenc#kw-aes192, 192",
426 "ec, secp521r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2001/04/xmlenc#kw-aes192, 192",
427 "xdh, X25519, http://www.w3.org/2021/04/xmldsig-more#x25519, http://www.w3.org/2001/04/xmlenc#kw-aes256, 256",
428 "xdh, X448, http://www.w3.org/2021/04/xmldsig-more#x448, http://www.w3.org/2001/04/xmlenc#kw-aes256, 256",
429 "ec, secp256r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2001/04/xmlenc#kw-aes256, 256",
430 "ec, secp384r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2001/04/xmlenc#kw-aes256, 256",
431 "ec, secp521r1, http://www.w3.org/2009/xmlenc11#ECDH-ES, http://www.w3.org/2001/04/xmlenc#kw-aes256, 256",
432 })
433 public void testEncryptionDecryptionWithKeyAgreementAndHKDF(String algorithm, String certAlias, String keyAgreementMethod, String keyWrapAlg, int keySize ) throws Exception {
434 String hkdfMacFunction = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256";
435 try {
436 if (!JDKTestUtils.isAlgorithmSupportedByJDK(algorithm)) {
437 LOG.info("Add AuxiliaryProvider to execute test with algorithm [{}] and cert alias [{}]", algorithm, certAlias);
438 Security.addProvider(JDKTestUtils.getAuxiliaryProvider());
439 } else if (JDKTestUtils.getJDKVersion() == 11 && algorithm.equals("xdh")) {
440
441
442
443 Security.insertProviderAt(JDKTestUtils.getAuxiliaryProvider(), 1);
444 }
445 Crypto encCrypto = CryptoFactory.getInstance("wss-ecdh.properties");
446
447 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
448 WSSecHeader secHeader = new WSSecHeader(doc);
449 secHeader.insertSecurityHeader();
450
451 HKDFParams keyDerivationParameters = HKDFParams.createBuilder(keySize, hkdfMacFunction)
452 .info("test-key-info".getBytes())
453 .salt(UUID.randomUUID().toString().getBytes())
454 .build();
455
456 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
457 builder.setUserInfo(certAlias);
458 builder.setKeyEncAlgo(keyWrapAlg);
459 builder.setKeyAgreementMethod(keyAgreementMethod);
460 builder.setKeyDerivationParameters(keyDerivationParameters);
461
462
463 LOG.info("Before Encryption ...");
464 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128_GCM);
465 SecretKey symmetricKey = keyGen.generateKey();
466
467 Document encryptedDoc = builder.build(encCrypto, symmetricKey);
468 LOG.info("After Encryption ....");
469
470 String outputString =
471 XMLUtils.prettyDocumentToString(encryptedDoc);
472
473 if (LOG.isDebugEnabled()) {
474 LOG.debug("Encrypted message:");
475 LOG.debug(outputString);
476 }
477 assertFalse(outputString.contains("counter_port_type"));
478
479 assertTrue(outputString.contains(EncryptionConstants._TAG_AGREEMENTMETHOD));
480 assertTrue(outputString.contains(EncryptionConstants._TAG_HKDFPARAMS));
481 assertTrue(outputString.contains(EncryptionConstants._TAG_INFO));
482 assertTrue(outputString.contains(EncryptionConstants._TAG_KEYLENGTH+">"+(keySize/8)+"</"));
483 assertTrue(outputString.contains(hkdfMacFunction));
484
485 assertTrue(outputString.contains(keyWrapAlg));
486 assertTrue(outputString.contains(keyAgreementMethod));
487
488 WSSecurityEngine newEngine = new WSSecurityEngine();
489 WSHandlerResult results =
490 newEngine.processSecurityHeader(encryptedDoc, null, keystoreCallbackHandler, encCrypto);
491
492 WSSecurityEngineResult actionResult =
493 results.getActionResults().get(WSConstants.ENCR).get(0);
494 assertNotNull(actionResult);
495 } finally {
496 Security.removeProvider(JDKTestUtils.getAuxiliaryProvider().getName());
497 }
498 }
499
500
501
502
503
504
505
506
507 @Test
508 public void testX509EncryptionThumb() throws Exception {
509 Crypto encCrypto = CryptoFactory.getInstance();
510 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
511 WSSecHeader secHeader = new WSSecHeader(doc);
512 secHeader.insertSecurityHeader();
513
514 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
515 builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
516 builder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
517
518 LOG.info("Before Encrypting ThumbprintSHA1....");
519 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
520 SecretKey symmetricKey = keyGen.generateKey();
521 Document encryptedDoc = builder.build(encCrypto, symmetricKey);
522
523 String outputString =
524 XMLUtils.prettyDocumentToString(encryptedDoc);
525 if (LOG.isDebugEnabled()) {
526 LOG.debug("Encrypted message with THUMBPRINT_IDENTIFIER:");
527 LOG.debug(outputString);
528 }
529 assertTrue(outputString.contains("#ThumbprintSHA1"));
530
531 LOG.info("After Encrypting ThumbprintSHA1....");
532 WSHandlerResult results = verify(encryptedDoc, encCrypto, keystoreCallbackHandler);
533
534 WSSecurityEngineResult actionResult =
535 results.getActionResults().get(WSConstants.ENCR).get(0);
536 assertNotNull(actionResult.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE));
537 assertNotNull(actionResult.get(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE));
538 REFERENCE_TYPE referenceType =
539 (REFERENCE_TYPE)actionResult.get(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE);
540 assertTrue(referenceType == REFERENCE_TYPE.THUMBPRINT_SHA1);
541 }
542
543
544
545
546
547
548
549
550 @Test
551 public void testX509EncryptionSHA1() throws Exception {
552 Crypto encCrypto = CryptoFactory.getInstance();
553 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
554 WSSecHeader secHeader = new WSSecHeader(doc);
555 secHeader.insertSecurityHeader();
556
557 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
558 builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
559 builder.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
560
561 LOG.info("Before Encrypting EncryptedKeySHA1....");
562 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
563 SecretKey symmetricKey = keyGen.generateKey();
564 Document encryptedDoc = builder.build(encCrypto, symmetricKey);
565
566 String outputString =
567 XMLUtils.prettyDocumentToString(encryptedDoc);
568 if (LOG.isDebugEnabled()) {
569 LOG.debug("Encrypted message with ENCRYPTED_KEY_SHA1_IDENTIFIER:");
570 LOG.debug(outputString);
571 }
572 assertTrue(outputString.contains("#EncryptedKeySHA1"));
573
574 LOG.info("After Encrypting EncryptedKeySHA1....");
575 verify(encryptedDoc, encCrypto, keystoreCallbackHandler);
576 }
577
578
579
580
581
582
583 @Test
584 public void testEncryptionX509SKI() throws Exception {
585 Crypto encCrypto = CryptoFactory.getInstance("wss-ecdh.properties");
586
587 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
588 WSSecHeader secHeader = new WSSecHeader(doc);
589 secHeader.insertSecurityHeader();
590
591 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
592 builder.setUserInfo("secp256r1");
593 builder.setKeyEncAlgo(WSConstants.KEYWRAP_AES128);
594 builder.setKeyAgreementMethod(WSConstants.AGREEMENT_METHOD_ECDH_ES);
595 builder.setKeyDerivationMethod(WSConstants.KEYDERIVATION_CONCATKDF);
596 builder.setDigestAlgorithm(WSS4JConstants.SHA256);
597 builder.setKeyIdentifierType(WSConstants.X509_SKI);
598
599 LOG.info("Before Encrypting X509SKI");
600 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128_GCM);
601 SecretKey symmetricKey = keyGen.generateKey();
602
603 Document encryptedDoc = builder.build(encCrypto, symmetricKey);
604 LOG.info("After Encrypting X509SKI");
605
606 String outputString =
607 XMLUtils.prettyDocumentToString(encryptedDoc);
608
609 if (LOG.isDebugEnabled()) {
610 LOG.debug("Encrypted message with X509SKI:");
611 LOG.debug(outputString);
612 }
613
614 assertTrue(outputString.contains("X509Data"));
615 assertTrue(outputString.contains("X509SKI"));
616
617 RequestData data = new RequestData();
618 data.setCallbackHandler(keystoreCallbackHandler);
619 data.setDecCrypto(encCrypto);
620 data.setIgnoredBSPRules(Collections.singletonList(BSPRule.R5426));
621 new WSSecurityEngine().processSecurityHeader(encryptedDoc, data);
622 }
623
624
625
626
627
628
629
630 @Test
631 public void testEncryptionSHA1Symmetric() throws Exception {
632 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
633 WSSecHeader secHeader = new WSSecHeader(doc);
634 secHeader.insertSecurityHeader();
635
636 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
637 builder.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
638 builder.setEncryptSymmKey(false);
639
640 LOG.info("Before Encrypting EncryptedKeySHA1....");
641 Document encryptedDoc = builder.build(crypto, key);
642
643 byte[] encodedBytes = KeyUtils.generateDigest(keyData);
644 String identifier = org.apache.xml.security.utils.XMLUtils.encodeToString(encodedBytes);
645 secretKeyCallbackHandler.addSecretKey(identifier, keyData);
646
647 String outputString =
648 XMLUtils.prettyDocumentToString(encryptedDoc);
649 if (LOG.isDebugEnabled()) {
650 LOG.debug("Encrypted message with ENCRYPTED_KEY_SHA1_IDENTIFIER:");
651 LOG.debug(outputString);
652 }
653 assertTrue(outputString.contains("#EncryptedKeySHA1"));
654
655 LOG.info("After Encrypting EncryptedKeySHA1....");
656 verify(encryptedDoc, null, secretKeyCallbackHandler);
657 }
658
659
660
661
662
663
664
665
666 @Test
667 public void testEncryptionSHA1SymmetricBytesHandler() throws Exception {
668 final WSSConfig cfg = WSSConfig.getNewInstance();
669 final RequestData reqData = new RequestData();
670 reqData.setWssConfig(cfg);
671 java.util.Map<String, Object> messageContext = new java.util.TreeMap<>();
672 messageContext.put(WSHandlerConstants.ENC_SYM_ENC_KEY, "false");
673 messageContext.put(WSHandlerConstants.ENC_KEY_ID, "EncryptedKeySHA1");
674 secretKeyCallbackHandler.setOutboundSecret(keyData);
675 messageContext.put(WSHandlerConstants.PW_CALLBACK_REF, secretKeyCallbackHandler);
676 reqData.setMsgContext(messageContext);
677 reqData.setUsername("");
678
679 final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
680 CustomHandler handler = new CustomHandler();
681 HandlerAction action = new HandlerAction(WSConstants.ENCR);
682 handler.send(
683 doc,
684 reqData,
685 Collections.singletonList(action),
686 true
687 );
688
689 String outputString =
690 XMLUtils.prettyDocumentToString(doc);
691 if (LOG.isDebugEnabled()) {
692 LOG.debug(outputString);
693 }
694
695 verify(doc, null, secretKeyCallbackHandler);
696 }
697
698
699
700
701
702
703
704
705
706
707
708
709 @Test
710 public void testEncryptionDecryptionRSA15STR() throws Exception {
711 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
712 WSSecHeader secHeader = new WSSecHeader(doc);
713 secHeader.insertSecurityHeader();
714
715 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
716 builder.setUserInfo("wss40");
717 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
718 builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
719 LOG.info("Before Encryption Triple DES....");
720
721
722
723
724 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.TRIPLE_DES);
725 SecretKey symmetricKey = keyGen.generateKey();
726 builder.prepare(crypto, symmetricKey);
727
728
729
730
731 SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc
732 .getDocumentElement());
733 WSEncryptionPart encP = new WSEncryptionPart(soapConstants
734 .getBodyQName().getLocalPart(), soapConstants.getEnvelopeURI(),
735 "Content");
736 builder.getParts().add(encP);
737
738
739
740
741
742
743
744 Element refs = builder.encrypt(symmetricKey);
745 builder.addExternalRefElement(refs);
746
747
748
749
750
751 builder.prependToHeader();
752
753 builder.prependBSTElementToHeader();
754
755 Document encryptedDoc = doc;
756 LOG.info("After Encryption Triple DES....");
757
758 String outputString =
759 XMLUtils.prettyDocumentToString(encryptedDoc);
760 if (LOG.isDebugEnabled()) {
761 LOG.debug("Encrypted message, RSA-15 keytransport, 3DES:");
762 LOG.debug(outputString);
763 }
764 assertFalse(outputString.contains("counter_port_type"));
765 WSHandlerResult results = verify(encryptedDoc, crypto, keystoreCallbackHandler);
766
767 outputString =
768 XMLUtils.prettyDocumentToString(encryptedDoc);
769 assertTrue(outputString.contains("counter_port_type"));
770
771 WSSecurityEngineResult actionResult =
772 results.getActionResults().get(WSConstants.ENCR).get(0);
773 assertNotNull(actionResult.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE));
774 assertNotNull(actionResult.get(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE));
775 REFERENCE_TYPE referenceType =
776 (REFERENCE_TYPE)actionResult.get(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE);
777 assertTrue(referenceType == REFERENCE_TYPE.DIRECT_REF);
778 }
779
780
781 @Test
782 public void testBadAttribute() throws Exception {
783 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
784 WSSecHeader secHeader = new WSSecHeader(doc);
785 secHeader.insertSecurityHeader();
786
787 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
788 builder.setUserInfo("wss40");
789 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
790 builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
791
792
793
794
795 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.TRIPLE_DES);
796 SecretKey symmetricKey = keyGen.generateKey();
797 builder.prepare(crypto, symmetricKey);
798
799
800
801
802 SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc
803 .getDocumentElement());
804 java.util.List<WSEncryptionPart> parts = new ArrayList<>();
805 WSEncryptionPart encP = new WSEncryptionPart(soapConstants
806 .getBodyQName().getLocalPart(), soapConstants.getEnvelopeURI(),
807 "Content");
808 parts.add(encP);
809
810
811
812
813
814
815
816 Element refs = builder.encrypt(symmetricKey);
817 builder.addExternalRefElement(refs);
818
819
820
821
822
823 Element encryptedKeyElement = builder.getEncryptedKeyElement();
824 encryptedKeyElement.setAttributeNS(null, "Type", "SomeType");
825 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), encryptedKeyElement);
826
827 builder.prependBSTElementToHeader();
828
829 Document encryptedDoc = doc;
830
831 String outputString =
832 XMLUtils.prettyDocumentToString(encryptedDoc);
833 if (LOG.isDebugEnabled()) {
834 LOG.debug(outputString);
835 }
836
837 WSSecurityEngine newEngine = new WSSecurityEngine();
838 try {
839 newEngine.processSecurityHeader(encryptedDoc, null, keystoreCallbackHandler, crypto);
840 fail("Failure expected on a bad attribute type");
841 } catch (WSSecurityException ex) {
842 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
843 }
844
845 RequestData data = new RequestData();
846 data.setCallbackHandler(keystoreCallbackHandler);
847 data.setDecCrypto(crypto);
848 data.setIgnoredBSPRules(Collections.singletonList(BSPRule.R3209));
849 newEngine.processSecurityHeader(encryptedDoc, data);
850 }
851
852
853
854
855
856 @Test
857 public void testEmbeddedEncryptedKey() throws Exception {
858 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
859 WSSecHeader secHeader = new WSSecHeader(doc);
860 secHeader.insertSecurityHeader();
861
862 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
863 builder.setUserInfo("wss40");
864 builder.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);
865 builder.setSymmetricEncAlgorithm(WSConstants.AES_128);
866
867 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
868 SecretKey symmetricKey = keyGen.generateKey();
869 builder.prepare(crypto, symmetricKey);
870 builder.setEmbedEncryptedKey(true);
871
872 SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc
873 .getDocumentElement());
874 java.util.List<WSEncryptionPart> parts = new ArrayList<>();
875 WSEncryptionPart encP = new WSEncryptionPart(soapConstants
876 .getBodyQName().getLocalPart(), soapConstants.getEnvelopeURI(),
877 "Content");
878 parts.add(encP);
879
880 builder.encrypt(symmetricKey);
881
882 String outputString =
883 XMLUtils.prettyDocumentToString(doc);
884 if (LOG.isDebugEnabled()) {
885 LOG.debug(outputString);
886 }
887
888 verify(doc, crypto, keystoreCallbackHandler);
889 }
890
891
892
893
894
895
896
897
898
899 @Test
900 public void testEncryptionDecryptionOAEPSHA256() throws Exception {
901 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
902 WSSecHeader secHeader = new WSSecHeader(doc);
903 secHeader.insertSecurityHeader();
904
905 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
906 builder.setUserInfo("wss40");
907 builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSAOAEP);
908 builder.setDigestAlgorithm(WSConstants.SHA256);
909
910 LOG.info("Before Encryption Triple DES/RSA-OAEP....");
911 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
912 SecretKey symmetricKey = keyGen.generateKey();
913 Document encryptedDoc = builder.build(crypto, symmetricKey);
914 LOG.info("After Encryption Triple DES/RSA-OAEP....");
915
916 String outputString =
917 XMLUtils.prettyDocumentToString(encryptedDoc);
918 if (LOG.isDebugEnabled()) {
919 LOG.debug("Encrypted message, RSA-OAEP keytransport, 3DES:");
920 LOG.debug(outputString);
921 }
922 assertFalse(outputString.contains("counter_port_type"));
923
924 WSSecurityEngine newEngine = new WSSecurityEngine();
925 WSHandlerResult results =
926 newEngine.processSecurityHeader(encryptedDoc, null, keystoreCallbackHandler, crypto);
927
928 WSSecurityEngineResult actionResult =
929 results.getActionResults().get(WSConstants.ENCR).get(0);
930 assertNotNull(actionResult);
931 }
932
933
934 @Test
935 public void testEncryptionWithRegexpCert() throws Exception {
936 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
937 WSSecHeader secHeader = new WSSecHeader(doc);
938 secHeader.insertSecurityHeader();
939
940 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
941 builder.setUserInfo("regexp");
942 builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
943 builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSAOAEP);
944 LOG.info("Before Encryption Triple DES/RSA-OAEP....");
945
946 Crypto regexpCrypto = CryptoFactory.getInstance("regexp.properties");
947 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
948 SecretKey symmetricKey = keyGen.generateKey();
949 Document encryptedDoc = builder.build(regexpCrypto, symmetricKey);
950 LOG.info("After Encryption Triple DES/RSA-OAEP....");
951
952 String outputString =
953 XMLUtils.prettyDocumentToString(encryptedDoc);
954 if (LOG.isDebugEnabled()) {
955 LOG.debug("Encrypted message, RSA-OAEP keytransport, 3DES:");
956 LOG.debug(outputString);
957 }
958 assertFalse(outputString.contains("counter_port_type"));
959
960 WSSecurityEngine newEngine = new WSSecurityEngine();
961 newEngine.processSecurityHeader(encryptedDoc, null, keystoreCallbackHandler, regexpCrypto);
962 }
963
964
965
966
967
968
969
970
971
972
973 private WSHandlerResult verify(
974 Document doc, Crypto decCrypto, CallbackHandler handler
975 ) throws Exception {
976 WSHandlerResult results =
977 secEngine.processSecurityHeader(doc, null, handler, decCrypto);
978 if (LOG.isDebugEnabled()) {
979 String outputString =
980 XMLUtils.prettyDocumentToString(doc);
981 LOG.debug(outputString);
982 }
983 return results;
984 }
985
986
987
988
989
990
991
992
993
994
995 @SuppressWarnings("unchecked")
996 private WSHandlerResult verify(
997 Document doc,
998 CallbackHandler handler,
999 javax.xml.namespace.QName expectedEncryptedElement
1000 ) throws Exception {
1001 final WSHandlerResult results =
1002 secEngine.processSecurityHeader(doc, null, handler, null, crypto);
1003 String outputString =
1004 XMLUtils.prettyDocumentToString(doc);
1005 if (LOG.isDebugEnabled()) {
1006 LOG.debug(outputString);
1007 }
1008 assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
1009
1010
1011
1012
1013
1014 boolean encrypted = false;
1015 for (WSSecurityEngineResult result : results.getResults()) {
1016 final Integer action = (Integer) result.get(WSSecurityEngineResult.TAG_ACTION);
1017 assertNotNull(action);
1018 if ((action & WSConstants.ENCR) != 0) {
1019 final java.util.List<WSDataRef> refs =
1020 (java.util.List<WSDataRef>) result.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
1021 assertNotNull(refs);
1022 encrypted = true;
1023 for (WSDataRef ref : refs) {
1024 assertNotNull(ref.getName());
1025 assertEquals(
1026 expectedEncryptedElement,
1027 ref.getName()
1028 );
1029 assertNotNull(ref.getProtectedElement());
1030 if (LOG.isDebugEnabled()) {
1031 LOG.debug("WSDataRef element: ");
1032 LOG.debug(
1033 DOM2Writer.nodeToString(ref.getProtectedElement())
1034 );
1035 }
1036 }
1037 }
1038 }
1039 assertTrue(encrypted);
1040 return results;
1041 }
1042
1043 }