1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.integration.test.kerberos;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.File;
24 import java.io.IOException;
25 import java.nio.charset.StandardCharsets;
26 import java.security.Principal;
27 import java.util.ArrayList;
28 import java.util.List;
29
30 import javax.crypto.SecretKey;
31 import javax.security.auth.callback.Callback;
32 import javax.security.auth.callback.CallbackHandler;
33 import javax.security.auth.callback.PasswordCallback;
34 import javax.security.auth.callback.UnsupportedCallbackException;
35 import javax.security.auth.kerberos.KerberosPrincipal;
36 import javax.xml.crypto.dsig.SignatureMethod;
37 import javax.xml.parsers.DocumentBuilderFactory;
38 import javax.xml.stream.XMLInputFactory;
39 import javax.xml.stream.XMLStreamReader;
40 import javax.xml.stream.XMLStreamWriter;
41 import javax.xml.transform.TransformerFactory;
42 import javax.xml.transform.dom.DOMSource;
43 import javax.xml.transform.stream.StreamResult;
44
45 import org.apache.kerby.kerberos.kerb.server.SimpleKdcServer;
46 import org.apache.wss4j.common.ext.WSSecurityException;
47 import org.apache.wss4j.common.kerberos.KerberosContextAndServiceNameCallback;
48 import org.apache.wss4j.common.spnego.SpnegoTokenContext;
49 import org.apache.wss4j.common.token.BinarySecurity;
50 import org.apache.wss4j.common.util.KeyUtils;
51 import org.apache.wss4j.common.util.SOAPUtil;
52 import org.apache.wss4j.common.util.XMLUtils;
53 import org.apache.wss4j.dom.WSConstants;
54
55 import org.apache.wss4j.dom.engine.WSSConfig;
56 import org.apache.wss4j.dom.engine.WSSecurityEngine;
57 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
58 import org.apache.wss4j.dom.handler.WSHandlerResult;
59 import org.apache.wss4j.dom.message.WSSecEncrypt;
60 import org.apache.wss4j.dom.message.WSSecHeader;
61 import org.apache.wss4j.dom.message.WSSecSignature;
62 import org.apache.wss4j.dom.message.token.KerberosSecurity;
63 import org.apache.wss4j.dom.util.WSSecurityUtil;
64 import org.apache.wss4j.dom.validate.KerberosTokenValidator;
65 import org.apache.wss4j.stax.ext.WSSConstants;
66 import org.apache.wss4j.stax.ext.WSSSecurityProperties;
67 import org.apache.wss4j.stax.securityEvent.KerberosTokenSecurityEvent;
68 import org.apache.wss4j.stax.setup.InboundWSSec;
69 import org.apache.wss4j.stax.setup.OutboundWSSec;
70 import org.apache.wss4j.stax.setup.WSSec;
71 import org.apache.wss4j.stax.test.utils.StAX2DOM;
72 import org.apache.wss4j.stax.test.utils.XmlReaderToWriter;
73 import org.apache.xml.security.exceptions.XMLSecurityException;
74 import org.apache.xml.security.stax.securityEvent.SecurityEvent;
75 import org.apache.xml.security.stax.securityEvent.SecurityEventListener;
76
77 import org.junit.jupiter.api.AfterAll;
78 import org.junit.jupiter.api.BeforeAll;
79 import org.junit.jupiter.api.Test;
80 import org.w3c.dom.Document;
81 import org.w3c.dom.NodeList;
82
83 import static org.junit.jupiter.api.Assertions.assertEquals;
84 import static org.junit.jupiter.api.Assertions.assertNotNull;
85 import static org.junit.jupiter.api.Assertions.assertTrue;
86 import static org.junit.jupiter.api.Assertions.fail;
87
88 public class KerberosTest {
89
90 private static final org.slf4j.Logger LOG =
91 org.slf4j.LoggerFactory.getLogger(KerberosTest.class);
92
93 private static final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
94 private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance();
95 private static DocumentBuilderFactory dbf;
96
97 private static boolean runTests = true;
98
99 private static SimpleKdcServer kerbyServer;
100
101 @BeforeAll
102 public static void setUp() throws Exception {
103
104 WSSConfig.init();
105
106 String basedir = System.getProperty("basedir");
107 if (basedir == null) {
108 basedir = new File(".").getCanonicalPath();
109 }
110
111
112 System.setProperty("java.security.auth.login.config", basedir + "/target/test-classes/kerberos/kerberos.jaas");
113 System.setProperty("java.security.krb5.conf", basedir + "/target/krb5.conf");
114
115 kerbyServer = new SimpleKdcServer();
116
117 kerbyServer.setKdcRealm("service.ws.apache.org");
118 kerbyServer.setAllowUdp(false);
119 kerbyServer.setWorkDir(new File(basedir + "/target"));
120
121
122
123 kerbyServer.init();
124
125
126 String alice = "alice@service.ws.apache.org";
127 String bob = "bob/service.ws.apache.org@service.ws.apache.org";
128
129 kerbyServer.createPrincipal(alice, "alice");
130 kerbyServer.createPrincipal(bob, "bob");
131
132 kerbyServer.start();
133
134 if ("IBM Corporation".equals(System.getProperty("java.vendor"))) {
135 runTests = false;
136 }
137
138 dbf = DocumentBuilderFactory.newInstance();
139 dbf.setNamespaceAware(true);
140 dbf.setIgnoringComments(false);
141 dbf.setCoalescing(false);
142 dbf.setIgnoringElementContentWhitespace(false);
143
144 xmlInputFactory.setProperty(XMLInputFactory.IS_COALESCING, false);
145 xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
146 }
147
148 @AfterAll
149 public static void tearDown() throws Exception {
150 if (kerbyServer != null) {
151 kerbyServer.stop();
152 }
153 }
154
155
156
157
158
159
160
161
162
163 @Test
164 public void testKerberosCreationAndProcessing() throws Exception {
165 if (!runTests) {
166 System.out.println("Skipping test because kerberos server could not be started");
167 return;
168 }
169
170 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
171
172 WSSecHeader secHeader = new WSSecHeader(doc);
173 secHeader.insertSecurityHeader();
174
175 KerberosSecurity bst = new KerberosSecurity(doc);
176 CallbackHandler callbackHandler = new CallbackHandler() {
177 @Override
178 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
179 PasswordCallback passwordCallback = (PasswordCallback)callbacks[0];
180 if (passwordCallback.getPrompt().contains("alice")) {
181 passwordCallback.setPassword("alice".toCharArray());
182 } else if (passwordCallback.getPrompt().contains("bob")) {
183 passwordCallback.setPassword("bob".toCharArray());
184 }
185 }
186 };
187 bst.retrieveServiceTicket("alice", callbackHandler, "bob@service.ws.apache.org");
188 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), bst.getElement());
189
190 if (LOG.isDebugEnabled()) {
191 String outputString =
192 XMLUtils.prettyDocumentToString(doc);
193 LOG.debug(outputString);
194 }
195
196
197 WSSConfig wssConfig = WSSConfig.getNewInstance();
198 KerberosTokenValidator validator = new KerberosTokenValidator();
199 validator.setContextName("bob");
200 validator.setServiceName("bob@service.ws.apache.org");
201 wssConfig.setValidator(WSConstants.BINARY_TOKEN, validator);
202 WSSecurityEngine secEngine = new WSSecurityEngine();
203 secEngine.setWssConfig(wssConfig);
204
205 WSHandlerResult results =
206 secEngine.processSecurityHeader(doc, null, callbackHandler, null);
207 WSSecurityEngineResult actionResult =
208 results.getActionResults().get(WSConstants.BST).get(0);
209 BinarySecurity token =
210 (BinarySecurity)actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
211 assertNotNull(token);
212
213 Principal principal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
214 assertTrue(principal instanceof KerberosPrincipal);
215 assertTrue(principal.getName().contains("alice"));
216 }
217
218
219
220
221 @Test
222 public void testSpnego() throws Exception {
223 if (!runTests) {
224 System.out.println("Skipping test because kerberos server could not be started");
225 return;
226 }
227
228 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
229
230 WSSecHeader secHeader = new WSSecHeader(doc);
231 secHeader.insertSecurityHeader();
232
233 SpnegoTokenContext spnegoToken = new SpnegoTokenContext();
234 CallbackHandler callbackHandler = new CallbackHandler() {
235 @Override
236 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
237 PasswordCallback passwordCallback = (PasswordCallback)callbacks[0];
238 if (passwordCallback.getPrompt().contains("alice")) {
239 passwordCallback.setPassword("alice".toCharArray());
240 } else if (passwordCallback.getPrompt().contains("bob")) {
241 passwordCallback.setPassword("bob".toCharArray());
242 }
243 }
244 };
245 spnegoToken.retrieveServiceTicket("alice", callbackHandler, "bob@service.ws.apache.org");
246
247 byte[] token = spnegoToken.getToken();
248 assertNotNull(token);
249
250 spnegoToken = new SpnegoTokenContext();
251 spnegoToken.validateServiceTicket("bob", callbackHandler, "bob@service.ws.apache.org", token);
252 assertTrue(spnegoToken.isEstablished());
253 }
254
255
256
257
258 @Test
259 public void testKerberosClient() throws Exception {
260 if (!runTests) {
261 System.out.println("Skipping test because kerberos server could not be started");
262 return;
263 }
264
265 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
266
267 CallbackHandler callbackHandler = new CallbackHandler() {
268 @Override
269 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
270 PasswordCallback passwordCallback = (PasswordCallback)callbacks[0];
271 if (passwordCallback.getPrompt().contains("alice")) {
272 passwordCallback.setPassword("alice".toCharArray());
273 } else if (passwordCallback.getPrompt().contains("bob")) {
274 passwordCallback.setPassword("bob".toCharArray());
275 }
276 }
277 };
278
279 try {
280 KerberosSecurity bst = new KerberosSecurity(doc);
281 bst.retrieveServiceTicket("alice2", callbackHandler, "bob@service");
282 fail("Failure expected on an unknown user");
283 } catch (WSSecurityException ex) {
284 assertTrue(ex.getMessage().startsWith("An error occurred in trying to obtain a TGT:"));
285 }
286
287
288 try {
289 KerberosSecurity bst = new KerberosSecurity(doc);
290 bst.retrieveServiceTicket("alice", callbackHandler, "bob2@service");
291 fail("Failure expected on an unknown user");
292 } catch (WSSecurityException ex) {
293 assertEquals(ex.getMessage(), "An error occurred in trying to obtain a service ticket");
294 }
295
296 }
297
298
299
300
301
302 @Test
303 public void testKerberosSignature() throws Exception {
304 if (!runTests) {
305 System.out.println("Skipping test because kerberos server could not be started");
306 return;
307 }
308
309 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
310
311 WSSecHeader secHeader = new WSSecHeader(doc);
312 secHeader.insertSecurityHeader();
313
314 KerberosSecurity bst = new KerberosSecurity(doc);
315 CallbackHandler callbackHandler = new CallbackHandler() {
316 @Override
317 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
318 if (callbacks[0] instanceof PasswordCallback) {
319 PasswordCallback passwordCallback = (PasswordCallback)callbacks[0];
320 if (passwordCallback.getPrompt().contains("alice")) {
321 passwordCallback.setPassword("alice".toCharArray());
322 } else if (passwordCallback.getPrompt().contains("bob")) {
323 passwordCallback.setPassword("bob".toCharArray());
324 }
325 }
326 }
327 };
328 bst.retrieveServiceTicket("alice", callbackHandler, "bob@service.ws.apache.org");
329 bst.setID("Id-" + bst.hashCode());
330 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), bst.getElement());
331
332 WSSecSignature sign = new WSSecSignature(secHeader);
333 sign.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
334 sign.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
335 sign.setCustomTokenId(bst.getID());
336 sign.setCustomTokenValueType(WSConstants.WSS_GSS_KRB_V5_AP_REQ);
337
338 SecretKey secretKey = bst.getSecretKey();
339 sign.setSecretKey(secretKey.getEncoded());
340
341 Document signedDoc = sign.build(null);
342
343 if (LOG.isDebugEnabled()) {
344 String outputString =
345 XMLUtils.prettyDocumentToString(signedDoc);
346 LOG.debug(outputString);
347 }
348
349
350 WSSConfig wssConfig = WSSConfig.getNewInstance();
351 KerberosTokenValidator validator = new KerberosTokenValidator();
352 validator.setContextName("bob");
353 validator.setServiceName("bob@service.ws.apache.org");
354 wssConfig.setValidator(WSConstants.BINARY_TOKEN, validator);
355 WSSecurityEngine secEngine = new WSSecurityEngine();
356 secEngine.setWssConfig(wssConfig);
357
358 WSHandlerResult results =
359 secEngine.processSecurityHeader(doc, null, callbackHandler, null);
360 WSSecurityEngineResult actionResult =
361 results.getActionResults().get(WSConstants.BST).get(0);
362 BinarySecurity token =
363 (BinarySecurity)actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
364 assertNotNull(token);
365
366 Principal principal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
367 assertTrue(principal instanceof KerberosPrincipal);
368 assertTrue(principal.getName().contains("alice"));
369 }
370
371
372
373
374
375
376 @Test
377 public void testKerberosSignatureKI() throws Exception {
378 if (!runTests) {
379 System.out.println("Skipping test because kerberos server could not be started");
380 return;
381 }
382
383 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
384
385 WSSecHeader secHeader = new WSSecHeader(doc);
386 secHeader.insertSecurityHeader();
387
388 KerberosSecurity bst = new KerberosSecurity(doc);
389 CallbackHandler callbackHandler = new CallbackHandler() {
390 @Override
391 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
392 if (callbacks[0] instanceof PasswordCallback) {
393 PasswordCallback passwordCallback = (PasswordCallback)callbacks[0];
394 if (passwordCallback.getPrompt().contains("alice")) {
395 passwordCallback.setPassword("alice".toCharArray());
396 } else if (passwordCallback.getPrompt().contains("bob")) {
397 passwordCallback.setPassword("bob".toCharArray());
398 }
399 }
400 }
401 };
402 bst.retrieveServiceTicket("alice", callbackHandler, "bob@service.ws.apache.org");
403 bst.setID("Id-" + bst.hashCode());
404
405 WSSecSignature sign = new WSSecSignature(secHeader);
406 sign.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
407 sign.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
408 sign.setCustomTokenValueType(WSConstants.WSS_KRB_KI_VALUE_TYPE);
409
410 SecretKey secretKey = bst.getSecretKey();
411 byte[] keyData = secretKey.getEncoded();
412 sign.setSecretKey(keyData);
413
414 byte[] digestBytes = KeyUtils.generateDigest(bst.getToken());
415 sign.setCustomTokenId(org.apache.xml.security.utils.XMLUtils.encodeToString(digestBytes));
416
417 Document signedDoc = sign.build(null);
418
419 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), bst.getElement());
420
421 if (LOG.isDebugEnabled()) {
422 String outputString =
423 XMLUtils.prettyDocumentToString(signedDoc);
424 LOG.debug(outputString);
425 }
426
427
428 WSSConfig wssConfig = WSSConfig.getNewInstance();
429 KerberosTokenValidator validator = new KerberosTokenValidator();
430 validator.setContextName("bob");
431 validator.setServiceName("bob@service.ws.apache.org");
432 wssConfig.setValidator(WSConstants.BINARY_TOKEN, validator);
433 WSSecurityEngine secEngine = new WSSecurityEngine();
434 secEngine.setWssConfig(wssConfig);
435
436 WSHandlerResult results =
437 secEngine.processSecurityHeader(doc, null, callbackHandler, null);
438 WSSecurityEngineResult actionResult =
439 results.getActionResults().get(WSConstants.BST).get(0);
440 BinarySecurity token =
441 (BinarySecurity)actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
442 assertNotNull(token);
443
444 Principal principal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
445 assertTrue(principal instanceof KerberosPrincipal);
446 assertTrue(principal.getName().contains("alice"));
447 }
448
449
450
451
452
453 @Test
454 public void testKerberosEncryption() throws Exception {
455 if (!runTests) {
456 System.out.println("Skipping test because kerberos server could not be started");
457 return;
458 }
459
460 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
461
462 WSSecHeader secHeader = new WSSecHeader(doc);
463 secHeader.insertSecurityHeader();
464
465 KerberosSecurity bst = new KerberosSecurity(doc);
466 CallbackHandler callbackHandler = new CallbackHandler() {
467 @Override
468 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
469 if (callbacks[0] instanceof PasswordCallback) {
470 PasswordCallback passwordCallback = (PasswordCallback)callbacks[0];
471 if (passwordCallback.getPrompt().contains("alice")) {
472 passwordCallback.setPassword("alice".toCharArray());
473 } else if (passwordCallback.getPrompt().contains("bob")) {
474 passwordCallback.setPassword("bob".toCharArray());
475 }
476 }
477 }
478 };
479 bst.retrieveServiceTicket("alice", callbackHandler, "bob@service.ws.apache.org");
480 bst.setID("Id-" + bst.hashCode());
481 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), bst.getElement());
482
483 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
484 builder.setSymmetricEncAlgorithm(WSConstants.AES_128);
485 SecretKey secretKey = bst.getSecretKey();
486 builder.setEncryptSymmKey(false);
487 builder.setCustomReferenceValue(WSConstants.WSS_GSS_KRB_V5_AP_REQ);
488 builder.setEncKeyId(bst.getID());
489
490 Document encryptedDoc = builder.build(null, secretKey);
491
492 if (LOG.isDebugEnabled()) {
493 String outputString =
494 XMLUtils.prettyDocumentToString(encryptedDoc);
495 LOG.debug(outputString);
496 }
497
498
499 WSSConfig wssConfig = WSSConfig.getNewInstance();
500 KerberosTokenValidator validator = new KerberosTokenValidator();
501 validator.setContextName("bob");
502 validator.setServiceName("bob@service.ws.apache.org");
503 wssConfig.setValidator(WSConstants.BINARY_TOKEN, validator);
504 WSSecurityEngine secEngine = new WSSecurityEngine();
505 secEngine.setWssConfig(wssConfig);
506
507 WSHandlerResult results =
508 secEngine.processSecurityHeader(encryptedDoc, null, callbackHandler, null);
509 WSSecurityEngineResult actionResult =
510 results.getActionResults().get(WSConstants.BST).get(0);
511 BinarySecurity token =
512 (BinarySecurity)actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
513 assertNotNull(token);
514
515 Principal principal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
516 assertTrue(principal instanceof KerberosPrincipal);
517 assertTrue(principal.getName().contains("alice"));
518 }
519
520
521
522
523
524 @Test
525 public void testKerberosEncryptionBSTFirst() throws Exception {
526 if (!runTests) {
527 System.out.println("Skipping test because kerberos server could not be started");
528 return;
529 }
530
531 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
532
533 WSSecHeader secHeader = new WSSecHeader(doc);
534 secHeader.insertSecurityHeader();
535
536 KerberosSecurity bst = new KerberosSecurity(doc);
537 CallbackHandler callbackHandler = new CallbackHandler() {
538 @Override
539 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
540 if (callbacks[0] instanceof PasswordCallback) {
541 PasswordCallback passwordCallback = (PasswordCallback)callbacks[0];
542 if (passwordCallback.getPrompt().contains("alice")) {
543 passwordCallback.setPassword("alice".toCharArray());
544 } else if (passwordCallback.getPrompt().contains("bob")) {
545 passwordCallback.setPassword("bob".toCharArray());
546 }
547 }
548 }
549 };
550 bst.retrieveServiceTicket("alice", callbackHandler, "bob@service.ws.apache.org");
551 bst.setID("Id-" + bst.hashCode());
552
553 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
554 builder.setSymmetricEncAlgorithm(WSConstants.AES_128);
555 SecretKey secretKey = bst.getSecretKey();
556 builder.setEncryptSymmKey(false);
557 builder.setCustomReferenceValue(WSConstants.WSS_GSS_KRB_V5_AP_REQ);
558 builder.setEncKeyId(bst.getID());
559
560 Document encryptedDoc = builder.build(null, secretKey);
561
562 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), bst.getElement());
563
564 if (LOG.isDebugEnabled()) {
565 String outputString =
566 XMLUtils.prettyDocumentToString(encryptedDoc);
567 LOG.debug(outputString);
568 }
569
570
571 WSSConfig wssConfig = WSSConfig.getNewInstance();
572 KerberosTokenValidator validator = new KerberosTokenValidator();
573 validator.setContextName("bob");
574 validator.setServiceName("bob@service.ws.apache.org");
575 wssConfig.setValidator(WSConstants.BINARY_TOKEN, validator);
576 WSSecurityEngine secEngine = new WSSecurityEngine();
577 secEngine.setWssConfig(wssConfig);
578
579 WSHandlerResult results =
580 secEngine.processSecurityHeader(encryptedDoc, null, callbackHandler, null);
581 WSSecurityEngineResult actionResult =
582 results.getActionResults().get(WSConstants.BST).get(0);
583 BinarySecurity token =
584 (BinarySecurity)actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
585 assertNotNull(token);
586
587 Principal principal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
588 assertTrue(principal instanceof KerberosPrincipal);
589 assertTrue(principal.getName().contains("alice"));
590 }
591
592
593
594
595
596 @Test
597 public void testKerberosEncryptionKI() throws Exception {
598 if (!runTests) {
599 System.out.println("Skipping test because kerberos server could not be started");
600 return;
601 }
602
603 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
604
605 WSSecHeader secHeader = new WSSecHeader(doc);
606 secHeader.insertSecurityHeader();
607
608 KerberosSecurity bst = new KerberosSecurity(doc);
609 CallbackHandler callbackHandler = new CallbackHandler() {
610 @Override
611 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
612 if (callbacks[0] instanceof PasswordCallback) {
613 PasswordCallback passwordCallback = (PasswordCallback)callbacks[0];
614 if (passwordCallback.getPrompt().contains("alice")) {
615 passwordCallback.setPassword("alice".toCharArray());
616 } else if (passwordCallback.getPrompt().contains("bob")) {
617 passwordCallback.setPassword("bob".toCharArray());
618 }
619 }
620 }
621 };
622 bst.retrieveServiceTicket("alice", callbackHandler, "bob@service.ws.apache.org");
623 bst.setID("Id-" + bst.hashCode());
624
625 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
626 builder.setSymmetricEncAlgorithm(WSConstants.AES_128);
627 SecretKey secretKey = bst.getSecretKey();
628 builder.setEncryptSymmKey(false);
629 builder.setCustomReferenceValue(WSConstants.WSS_KRB_KI_VALUE_TYPE);
630
631 byte[] digestBytes = KeyUtils.generateDigest(bst.getToken());
632 builder.setEncKeyId(org.apache.xml.security.utils.XMLUtils.encodeToString(digestBytes));
633
634 Document encryptedDoc = builder.build(null, secretKey);
635
636 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), bst.getElement());
637
638 if (LOG.isDebugEnabled()) {
639 String outputString =
640 XMLUtils.prettyDocumentToString(encryptedDoc);
641 LOG.debug(outputString);
642 }
643
644
645 WSSConfig wssConfig = WSSConfig.getNewInstance();
646 KerberosTokenValidator validator = new KerberosTokenValidator();
647 validator.setContextName("bob");
648 validator.setServiceName("bob@service.ws.apache.org");
649 wssConfig.setValidator(WSConstants.BINARY_TOKEN, validator);
650 WSSecurityEngine secEngine = new WSSecurityEngine();
651 secEngine.setWssConfig(wssConfig);
652
653 WSHandlerResult results =
654 secEngine.processSecurityHeader(encryptedDoc, null, callbackHandler, null);
655 WSSecurityEngineResult actionResult =
656 results.getActionResults().get(WSConstants.BST).get(0);
657 BinarySecurity token =
658 (BinarySecurity)actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
659 assertNotNull(token);
660
661 Principal principal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
662 assertTrue(principal instanceof KerberosPrincipal);
663 assertTrue(principal.getName().contains("alice"));
664 }
665
666
667
668
669 @Test
670 public void testKerberosSignatureOutbound() throws Exception {
671 if (!runTests) {
672 System.out.println("Skipping test because kerberos server could not be started");
673 return;
674 }
675
676 Document document;
677 {
678 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
679 List<WSSConstants.Action> actions = new ArrayList<>();
680 actions.add(WSSConstants.SIGNATURE_WITH_KERBEROS_TOKEN);
681 securityProperties.setActions(actions);
682 securityProperties.setCallbackHandler(new CallbackHandler() {
683 @Override
684 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
685 if (callbacks[0] instanceof KerberosContextAndServiceNameCallback) {
686 KerberosContextAndServiceNameCallback kerberosContextAndServiceNameCallback =
687 (KerberosContextAndServiceNameCallback) callbacks[0];
688 kerberosContextAndServiceNameCallback.setContextName("alice");
689 kerberosContextAndServiceNameCallback.setServiceName("bob@service.ws.apache.org");
690 } else if (callbacks[0] instanceof PasswordCallback) {
691 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
692 if (passwordCallback.getPrompt().contains("alice")) {
693 passwordCallback.setPassword("alice".toCharArray());
694 }
695 }
696 }
697 });
698
699 ByteArrayOutputStream baos = new ByteArrayOutputStream();
700
701 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
702 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<>());
703 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
704 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
705 xmlStreamWriter.close();
706
707 document = dbf.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
708 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
709 assertEquals(nodeList.getLength(), 1);
710 }
711
712
713 {
714
715 WSSConfig wssConfig = WSSConfig.getNewInstance();
716 KerberosTokenValidator validator = new KerberosTokenValidator();
717 validator.setContextName("bob");
718 validator.setServiceName("bob@service.ws.apache.org");
719 wssConfig.setValidator(WSConstants.BINARY_TOKEN, validator);
720 WSSecurityEngine secEngine = new WSSecurityEngine();
721 secEngine.setWssConfig(wssConfig);
722
723 CallbackHandler callbackHandler = new CallbackHandler() {
724 @Override
725 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
726 if (callbacks[0] instanceof PasswordCallback) {
727 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
728 if (passwordCallback.getPrompt().contains("bob")) {
729 passwordCallback.setPassword("bob".toCharArray());
730 }
731 }
732 }
733 };
734
735 WSHandlerResult results =
736 secEngine.processSecurityHeader(document, null, callbackHandler, null);
737 WSSecurityEngineResult actionResult =
738 results.getActionResults().get(WSConstants.BST).get(0);
739 BinarySecurity token =
740 (BinarySecurity) actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
741 assertNotNull(token);
742
743 Principal principal = (Principal) actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
744 assertTrue(principal instanceof KerberosPrincipal);
745 assertTrue(principal.getName().contains("alice"));
746 }
747 }
748
749 @Test
750 public void testKerberosSignatureInbound() throws Exception {
751 if (!runTests) {
752 System.out.println("Skipping test because kerberos server could not be started");
753 return;
754 }
755
756 ByteArrayOutputStream baos = new ByteArrayOutputStream();
757 {
758 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
759
760 WSSecHeader secHeader = new WSSecHeader(doc);
761 secHeader.insertSecurityHeader();
762
763 KerberosSecurity bst = new KerberosSecurity(doc);
764 CallbackHandler callbackHandler = new CallbackHandler() {
765 @Override
766 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
767 if (callbacks[0] instanceof PasswordCallback) {
768 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
769 if (passwordCallback.getPrompt().contains("alice")) {
770 passwordCallback.setPassword("alice".toCharArray());
771 }
772 }
773 }
774 };
775 bst.retrieveServiceTicket("alice", callbackHandler, "bob@service.ws.apache.org");
776 bst.setID("Id-" + bst.hashCode());
777
778 WSSecSignature sign = new WSSecSignature(secHeader);
779 sign.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
780 sign.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
781 sign.setCustomTokenId(bst.getID());
782 sign.setCustomTokenValueType(WSConstants.WSS_GSS_KRB_V5_AP_REQ);
783
784 SecretKey secretKey = bst.getSecretKey();
785 sign.setSecretKey(secretKey.getEncoded());
786
787 sign.build(null);
788 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), bst.getElement());
789
790 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
791 transformer.transform(new DOMSource(doc), new StreamResult(baos));
792 }
793
794 {
795 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
796 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
797 securityProperties.setCallbackHandler(new CallbackHandler() {
798 @Override
799 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
800 if (callbacks[0] instanceof PasswordCallback) {
801 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
802 if (passwordCallback.getPrompt().contains("bob")) {
803 passwordCallback.setPassword("bob".toCharArray());
804 }
805 } else if (callbacks[0] instanceof KerberosContextAndServiceNameCallback) {
806 KerberosContextAndServiceNameCallback cb = (KerberosContextAndServiceNameCallback) callbacks[0];
807 cb.setContextName("bob");
808 cb.setServiceName("bob@service.ws.apache.org");
809 }
810 }
811 });
812
813 final List<KerberosTokenSecurityEvent> kerberosTokenSecurityEvents = new ArrayList<>();
814
815 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
816 SecurityEventListener securityEventListener = new SecurityEventListener() {
817 @Override
818 public void registerSecurityEvent(SecurityEvent securityEvent) throws XMLSecurityException {
819 if (securityEvent instanceof KerberosTokenSecurityEvent) {
820 kerberosTokenSecurityEvents.add((KerberosTokenSecurityEvent) securityEvent);
821 }
822 }
823 };
824 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(
825 new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
826
827 Document document = StAX2DOM.readDoc(dbf.newDocumentBuilder(), xmlStreamReader);
828
829
830 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
831 assertEquals(nodeList.getLength(), 1);
832 assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
833
834 assertEquals(kerberosTokenSecurityEvents.size(), 1);
835 final KerberosTokenSecurityEvent kerberosTokenSecurityEvent = kerberosTokenSecurityEvents.get(0);
836 assertNotNull(kerberosTokenSecurityEvent.getSecurityToken().getSubject());
837 assertTrue(kerberosTokenSecurityEvent.getSecurityToken().getPrincipal() instanceof KerberosPrincipal);
838 assertEquals(kerberosTokenSecurityEvent.getSecurityToken().getPrincipal().getName(), "alice@service.ws.apache.org");
839 }
840 }
841
842 @Test
843 public void testKerberosSignatureKIInbound() throws Exception {
844 if (!runTests) {
845 System.out.println("Skipping test because kerberos server could not be started");
846 return;
847 }
848
849 ByteArrayOutputStream baos = new ByteArrayOutputStream();
850 {
851 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
852
853 WSSecHeader secHeader = new WSSecHeader(doc);
854 secHeader.insertSecurityHeader();
855
856 KerberosSecurity bst = new KerberosSecurity(doc);
857 CallbackHandler callbackHandler = new CallbackHandler() {
858 @Override
859 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
860 if (callbacks[0] instanceof PasswordCallback) {
861 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
862 if (passwordCallback.getPrompt().contains("alice")) {
863 passwordCallback.setPassword("alice".toCharArray());
864 }
865 }
866 }
867 };
868 bst.retrieveServiceTicket("alice", callbackHandler, "bob@service.ws.apache.org");
869 bst.setID("Id-" + bst.hashCode());
870
871 WSSecSignature sign = new WSSecSignature(secHeader);
872 sign.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
873 sign.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
874 sign.setCustomTokenValueType(WSConstants.WSS_KRB_KI_VALUE_TYPE);
875
876 SecretKey secretKey = bst.getSecretKey();
877 byte[] keyData = secretKey.getEncoded();
878 sign.setSecretKey(keyData);
879
880 byte[] digestBytes = KeyUtils.generateDigest(bst.getToken());
881 sign.setCustomTokenId(org.apache.xml.security.utils.XMLUtils.encodeToString(digestBytes));
882
883 sign.build(null);
884
885 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), bst.getElement());
886
887 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
888 transformer.transform(new DOMSource(doc), new StreamResult(baos));
889 }
890
891 {
892 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
893 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
894 securityProperties.setCallbackHandler(new CallbackHandler() {
895 @Override
896 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
897 if (callbacks[0] instanceof PasswordCallback) {
898 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
899 if (passwordCallback.getPrompt().contains("bob")) {
900 passwordCallback.setPassword("bob".toCharArray());
901 }
902 } else if (callbacks[0] instanceof KerberosContextAndServiceNameCallback) {
903 KerberosContextAndServiceNameCallback cb = (KerberosContextAndServiceNameCallback) callbacks[0];
904 cb.setContextName("bob");
905 cb.setServiceName("bob@service.ws.apache.org");
906 }
907 }
908 });
909
910 final List<KerberosTokenSecurityEvent> kerberosTokenSecurityEvents = new ArrayList<>();
911
912 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
913 SecurityEventListener securityEventListener = new SecurityEventListener() {
914 @Override
915 public void registerSecurityEvent(SecurityEvent securityEvent) throws XMLSecurityException {
916 if (securityEvent instanceof KerberosTokenSecurityEvent) {
917 kerberosTokenSecurityEvents.add((KerberosTokenSecurityEvent) securityEvent);
918 }
919 }
920 };
921 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(
922 new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
923
924 Document document = StAX2DOM.readDoc(dbf.newDocumentBuilder(), xmlStreamReader);
925
926
927 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
928 assertEquals(nodeList.getLength(), 1);
929 assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
930
931 assertEquals(kerberosTokenSecurityEvents.size(), 1);
932 }
933 }
934
935 @Test
936 public void testKerberosEncryptionOutbound() throws Exception {
937 if (!runTests) {
938 System.out.println("Skipping test because kerberos server could not be started");
939 return;
940 }
941
942 Document document;
943 {
944 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
945 List<WSSConstants.Action> actions = new ArrayList<>();
946 actions.add(WSSConstants.ENCRYPTION_WITH_KERBEROS_TOKEN);
947 securityProperties.setActions(actions);
948 securityProperties.setEncryptionSymAlgorithm(WSSConstants.NS_XENC_AES128);
949 securityProperties.setCallbackHandler(new CallbackHandler() {
950 @Override
951 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
952 if (callbacks[0] instanceof KerberosContextAndServiceNameCallback) {
953 KerberosContextAndServiceNameCallback kerberosContextAndServiceNameCallback =
954 (KerberosContextAndServiceNameCallback) callbacks[0];
955 kerberosContextAndServiceNameCallback.setContextName("alice");
956 kerberosContextAndServiceNameCallback.setServiceName("bob@service.ws.apache.org");
957 } else if (callbacks[0] instanceof PasswordCallback) {
958 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
959 if (passwordCallback.getPrompt().contains("alice")) {
960 passwordCallback.setPassword("alice".toCharArray());
961 }
962 }
963 }
964 });
965
966 ByteArrayOutputStream baos = new ByteArrayOutputStream();
967
968 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
969 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<>());
970 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
971 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
972 xmlStreamWriter.close();
973
974 document = dbf.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
975 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_ReferenceList.getNamespaceURI(), WSSConstants.TAG_xenc_ReferenceList.getLocalPart());
976 assertEquals(1, nodeList.getLength());
977 }
978
979 {
980
981 WSSConfig wssConfig = WSSConfig.getNewInstance();
982 KerberosTokenValidator validator = new KerberosTokenValidator();
983 validator.setContextName("bob");
984 validator.setServiceName("bob@service.ws.apache.org");
985 wssConfig.setValidator(WSConstants.BINARY_TOKEN, validator);
986 WSSecurityEngine secEngine = new WSSecurityEngine();
987 secEngine.setWssConfig(wssConfig);
988
989 CallbackHandler callbackHandler = new CallbackHandler() {
990 @Override
991 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
992 if (callbacks[0] instanceof PasswordCallback) {
993 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
994 if (passwordCallback.getPrompt().contains("bob")) {
995 passwordCallback.setPassword("bob".toCharArray());
996 }
997 }
998 }
999 };
1000
1001 WSHandlerResult results =
1002 secEngine.processSecurityHeader(document, null, callbackHandler, null);
1003 WSSecurityEngineResult actionResult =
1004 results.getActionResults().get(WSConstants.BST).get(0);
1005 BinarySecurity token =
1006 (BinarySecurity) actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
1007 assertNotNull(token);
1008
1009 Principal principal = (Principal) actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
1010 assertTrue(principal instanceof KerberosPrincipal);
1011 assertTrue(principal.getName().contains("alice"));
1012 }
1013 }
1014
1015 @Test
1016 public void testKerberosEncryptionOutboundDeprecatedTag() throws Exception {
1017 if (!runTests) {
1018 System.out.println("Skipping test because kerberos server could not be started");
1019 return;
1020 }
1021
1022 Document document;
1023 {
1024 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1025 List<WSSConstants.Action> actions = new ArrayList<>();
1026 actions.add(WSSConstants.ENCRYPT_WITH_KERBEROS_TOKEN);
1027 securityProperties.setActions(actions);
1028 securityProperties.setEncryptionSymAlgorithm(WSSConstants.NS_XENC_AES128);
1029 securityProperties.setCallbackHandler(new CallbackHandler() {
1030 @Override
1031 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
1032 if (callbacks[0] instanceof KerberosContextAndServiceNameCallback) {
1033 KerberosContextAndServiceNameCallback kerberosContextAndServiceNameCallback =
1034 (KerberosContextAndServiceNameCallback) callbacks[0];
1035 kerberosContextAndServiceNameCallback.setContextName("alice");
1036 kerberosContextAndServiceNameCallback.setServiceName("bob@service.ws.apache.org");
1037 } else if (callbacks[0] instanceof PasswordCallback) {
1038 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
1039 if (passwordCallback.getPrompt().contains("alice")) {
1040 passwordCallback.setPassword("alice".toCharArray());
1041 }
1042 }
1043 }
1044 });
1045
1046 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1047
1048 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
1049 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<>());
1050 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
1051 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
1052 xmlStreamWriter.close();
1053
1054 document = dbf.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1055 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_ReferenceList.getNamespaceURI(), WSSConstants.TAG_xenc_ReferenceList.getLocalPart());
1056 assertEquals(1, nodeList.getLength());
1057 }
1058
1059 {
1060
1061 WSSConfig wssConfig = WSSConfig.getNewInstance();
1062 KerberosTokenValidator validator = new KerberosTokenValidator();
1063 validator.setContextName("bob");
1064 validator.setServiceName("bob@service.ws.apache.org");
1065 wssConfig.setValidator(WSConstants.BINARY_TOKEN, validator);
1066 WSSecurityEngine secEngine = new WSSecurityEngine();
1067 secEngine.setWssConfig(wssConfig);
1068
1069 CallbackHandler callbackHandler = new CallbackHandler() {
1070 @Override
1071 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
1072 if (callbacks[0] instanceof PasswordCallback) {
1073 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
1074 if (passwordCallback.getPrompt().contains("bob")) {
1075 passwordCallback.setPassword("bob".toCharArray());
1076 }
1077 }
1078 }
1079 };
1080
1081 WSHandlerResult results =
1082 secEngine.processSecurityHeader(document, null, callbackHandler, null);
1083 WSSecurityEngineResult actionResult =
1084 results.getActionResults().get(WSConstants.BST).get(0);
1085 BinarySecurity token =
1086 (BinarySecurity) actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
1087 assertNotNull(token);
1088
1089 Principal principal = (Principal) actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
1090 assertTrue(principal instanceof KerberosPrincipal);
1091 assertTrue(principal.getName().contains("alice"));
1092 }
1093 }
1094
1095 @Test
1096 public void testKerberosEncryptionInbound() throws Exception {
1097 if (!runTests) {
1098 System.out.println("Skipping test because kerberos server could not be started");
1099 return;
1100 }
1101
1102 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1103 {
1104 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1105
1106 WSSecHeader secHeader = new WSSecHeader(doc);
1107 secHeader.insertSecurityHeader();
1108
1109 KerberosSecurity bst = new KerberosSecurity(doc);
1110 CallbackHandler callbackHandler = new CallbackHandler() {
1111 @Override
1112 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
1113 if (callbacks[0] instanceof PasswordCallback) {
1114 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
1115 if (passwordCallback.getPrompt().contains("alice")) {
1116 passwordCallback.setPassword("alice".toCharArray());
1117 }
1118 }
1119 }
1120 };
1121 bst.retrieveServiceTicket("alice", callbackHandler, "bob@service.ws.apache.org");
1122 bst.setID("Id-" + bst.hashCode());
1123
1124 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
1125 builder.setSymmetricEncAlgorithm(WSConstants.AES_256);
1126 SecretKey secretKey = bst.getSecretKey();
1127 builder.setEncryptSymmKey(false);
1128 builder.setCustomReferenceValue(WSConstants.WSS_GSS_KRB_V5_AP_REQ);
1129 builder.setEncKeyId(bst.getID());
1130 builder.build(null, secretKey);
1131 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), bst.getElement());
1132
1133 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1134 transformer.transform(new DOMSource(doc), new StreamResult(baos));
1135 }
1136
1137 {
1138 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1139 securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1140 securityProperties.setCallbackHandler(new CallbackHandler() {
1141 @Override
1142 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
1143 if (callbacks[0] instanceof PasswordCallback) {
1144 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
1145 if (passwordCallback.getPrompt().contains("bob")) {
1146 passwordCallback.setPassword("bob".toCharArray());
1147 }
1148 } else if (callbacks[0] instanceof KerberosContextAndServiceNameCallback) {
1149 KerberosContextAndServiceNameCallback cb = (KerberosContextAndServiceNameCallback) callbacks[0];
1150 cb.setContextName("bob");
1151 cb.setServiceName("bob@service.ws.apache.org");
1152 }
1153 }
1154 });
1155
1156 final List<KerberosTokenSecurityEvent> kerberosTokenSecurityEvents = new ArrayList<>();
1157
1158 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
1159 SecurityEventListener securityEventListener = new SecurityEventListener() {
1160 @Override
1161 public void registerSecurityEvent(SecurityEvent securityEvent) throws XMLSecurityException {
1162 if (securityEvent instanceof KerberosTokenSecurityEvent) {
1163 kerberosTokenSecurityEvents.add((KerberosTokenSecurityEvent) securityEvent);
1164 }
1165 }
1166 };
1167 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(
1168 new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
1169
1170 Document document = StAX2DOM.readDoc(dbf.newDocumentBuilder(), xmlStreamReader);
1171
1172
1173 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN.getNamespaceURI(), WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN.getLocalPart());
1174 assertEquals(nodeList.getLength(), 1);
1175 assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1176
1177
1178 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1179 assertEquals(nodeList.getLength(), 0);
1180
1181 assertEquals(kerberosTokenSecurityEvents.size(), 1);
1182 }
1183 }
1184
1185 @Test
1186 public void testKerberosEncryptionKIInbound() throws Exception {
1187 if (!runTests) {
1188 System.out.println("Skipping test because kerberos server could not be started");
1189 return;
1190 }
1191
1192 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1193 {
1194 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1195
1196 WSSecHeader secHeader = new WSSecHeader(doc);
1197 secHeader.insertSecurityHeader();
1198
1199 KerberosSecurity bst = new KerberosSecurity(doc);
1200 CallbackHandler callbackHandler = new CallbackHandler() {
1201 @Override
1202 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
1203 if (callbacks[0] instanceof PasswordCallback) {
1204 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
1205 if (passwordCallback.getPrompt().contains("alice")) {
1206 passwordCallback.setPassword("alice".toCharArray());
1207 }
1208 }
1209 }
1210 };
1211 bst.retrieveServiceTicket("alice", callbackHandler, "bob@service.ws.apache.org");
1212 bst.setID("Id-" + bst.hashCode());
1213
1214 WSSecEncrypt builder = new WSSecEncrypt(secHeader);
1215 builder.setSymmetricEncAlgorithm(WSConstants.AES_128);
1216 SecretKey secretKey = bst.getSecretKey();
1217 builder.setEncryptSymmKey(false);
1218 builder.setCustomReferenceValue(WSConstants.WSS_KRB_KI_VALUE_TYPE);
1219
1220 byte[] digestBytes = KeyUtils.generateDigest(bst.getToken());
1221 builder.setEncKeyId(org.apache.xml.security.utils.XMLUtils.encodeToString(digestBytes));
1222
1223 builder.build(null, secretKey);
1224
1225 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), bst.getElement());
1226
1227 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1228 transformer.transform(new DOMSource(doc), new StreamResult(baos));
1229
1230 }
1231
1232 {
1233 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1234 securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1235 securityProperties.setCallbackHandler(new CallbackHandler() {
1236 @Override
1237 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
1238 if (callbacks[0] instanceof PasswordCallback) {
1239 PasswordCallback passwordCallback = (PasswordCallback) callbacks[0];
1240 if (passwordCallback.getPrompt().contains("bob")) {
1241 passwordCallback.setPassword("bob".toCharArray());
1242 }
1243 } else if (callbacks[0] instanceof KerberosContextAndServiceNameCallback) {
1244 KerberosContextAndServiceNameCallback cb = (KerberosContextAndServiceNameCallback) callbacks[0];
1245 cb.setContextName("bob");
1246 cb.setServiceName("bob@service.ws.apache.org");
1247 }
1248 }
1249 });
1250
1251 final List<KerberosTokenSecurityEvent> kerberosTokenSecurityEvents = new ArrayList<>();
1252
1253 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
1254 SecurityEventListener securityEventListener = new SecurityEventListener() {
1255 @Override
1256 public void registerSecurityEvent(SecurityEvent securityEvent) throws XMLSecurityException {
1257 if (securityEvent instanceof KerberosTokenSecurityEvent) {
1258 kerberosTokenSecurityEvents.add((KerberosTokenSecurityEvent) securityEvent);
1259 }
1260 }
1261 };
1262 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(
1263 new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
1264
1265 Document document = StAX2DOM.readDoc(dbf.newDocumentBuilder(), xmlStreamReader);
1266
1267
1268 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN.getNamespaceURI(), WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN.getLocalPart());
1269 assertEquals(nodeList.getLength(), 1);
1270 assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1271
1272
1273 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1274 assertEquals(nodeList.getLength(), 0);
1275
1276 assertEquals(kerberosTokenSecurityEvents.size(), 1);
1277 }
1278 }
1279
1280 }