1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.stax.setup;
20
21 import java.io.OutputStream;
22 import java.security.Key;
23 import java.security.NoSuchAlgorithmException;
24 import java.security.PublicKey;
25 import java.security.cert.X509Certificate;
26 import java.util.List;
27
28 import javax.crypto.KeyGenerator;
29 import javax.crypto.spec.SecretKeySpec;
30 import javax.xml.parsers.ParserConfigurationException;
31 import javax.xml.stream.XMLStreamWriter;
32
33 import org.apache.wss4j.common.crypto.Crypto;
34 import org.apache.wss4j.common.crypto.CryptoType;
35 import org.apache.wss4j.common.ext.WSPasswordCallback;
36 import org.apache.wss4j.common.ext.WSSecurityException;
37 import org.apache.wss4j.stax.ext.DocumentCreatorImpl;
38 import org.apache.wss4j.stax.ext.WSSConstants;
39 import org.apache.wss4j.stax.ext.WSSSecurityProperties;
40 import org.apache.wss4j.stax.impl.processor.output.BinarySecurityTokenOutputProcessor;
41 import org.apache.wss4j.stax.impl.processor.output.CustomTokenOutputProcessor;
42 import org.apache.wss4j.stax.impl.processor.output.DerivedKeyTokenOutputProcessor;
43 import org.apache.wss4j.stax.impl.processor.output.EncryptEndingOutputProcessor;
44 import org.apache.wss4j.stax.impl.processor.output.EncryptOutputProcessor;
45 import org.apache.wss4j.stax.impl.processor.output.EncryptedKeyOutputProcessor;
46 import org.apache.wss4j.stax.impl.processor.output.ReferenceListOutputProcessor;
47 import org.apache.wss4j.stax.impl.processor.output.SAMLTokenOutputProcessor;
48 import org.apache.wss4j.stax.impl.processor.output.SecurityContextTokenOutputProcessor;
49 import org.apache.wss4j.stax.impl.processor.output.SecurityHeaderOutputProcessor;
50 import org.apache.wss4j.stax.impl.processor.output.SecurityHeaderReorderProcessor;
51 import org.apache.wss4j.stax.impl.processor.output.SignatureConfirmationOutputProcessor;
52 import org.apache.wss4j.stax.impl.processor.output.TimestampOutputProcessor;
53 import org.apache.wss4j.stax.impl.processor.output.UsernameTokenOutputProcessor;
54 import org.apache.wss4j.stax.impl.processor.output.WSSSignatureOutputProcessor;
55 import org.apache.wss4j.stax.impl.securityToken.KerberosClientSecurityToken;
56 import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
57 import org.apache.wss4j.stax.utils.WSSUtils;
58 import org.apache.xml.security.exceptions.XMLSecurityException;
59 import org.apache.xml.security.stax.config.JCEAlgorithmMapper;
60 import org.apache.xml.security.stax.ext.OutboundSecurityContext;
61 import org.apache.xml.security.stax.ext.OutputProcessor;
62 import org.apache.xml.security.stax.ext.SecurityContext;
63 import org.apache.xml.security.stax.ext.XMLSecurityConstants;
64 import org.apache.xml.security.stax.impl.DocumentContextImpl;
65 import org.apache.xml.security.stax.impl.OutboundSecurityContextImpl;
66 import org.apache.xml.security.stax.impl.OutputProcessorChainImpl;
67 import org.apache.xml.security.stax.impl.XMLSecurityStreamWriter;
68 import org.apache.xml.security.stax.impl.processor.output.FinalOutputProcessor;
69 import org.apache.xml.security.stax.impl.securityToken.GenericOutboundSecurityToken;
70 import org.apache.xml.security.stax.impl.util.IDGenerator;
71 import org.apache.xml.security.stax.securityEvent.SecurityEvent;
72 import org.apache.xml.security.stax.securityEvent.SecurityEventListener;
73 import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
74 import org.apache.xml.security.stax.securityToken.OutboundSecurityToken;
75 import org.apache.xml.security.stax.securityToken.SecurityToken;
76 import org.apache.xml.security.stax.securityToken.SecurityTokenConstants.TokenUsage;
77 import org.apache.xml.security.stax.securityToken.SecurityTokenProvider;
78
79
80
81
82
83 public class OutboundWSSec {
84
85 private final WSSSecurityProperties securityProperties;
86
87 public OutboundWSSec(WSSSecurityProperties securityProperties) {
88 this.securityProperties = securityProperties;
89 }
90
91
92
93
94
95
96
97
98
99 public XMLStreamWriter processOutMessage(
100 OutputStream outputStream, String encoding,
101 List<SecurityEvent> requestSecurityEvents) throws WSSecurityException {
102 return processOutMessage(outputStream, encoding, requestSecurityEvents, null);
103 }
104
105
106
107
108
109
110
111
112
113 public XMLStreamWriter processOutMessage(
114 XMLStreamWriter xmlStreamWriter, String encoding,
115 List<SecurityEvent> requestSecurityEvents) throws WSSecurityException {
116 return processOutMessage(xmlStreamWriter, encoding, requestSecurityEvents, null);
117 }
118
119
120
121
122
123
124
125
126
127 public XMLStreamWriter processOutMessage(
128 OutputStream outputStream, String encoding, List<SecurityEvent> requestSecurityEvents,
129 SecurityEventListener securityEventListener) throws WSSecurityException {
130 final OutboundSecurityContextImpl outboundSecurityContext = new OutboundSecurityContextImpl();
131 outboundSecurityContext.putList(SecurityEvent.class, requestSecurityEvents);
132 outboundSecurityContext.addSecurityEventListener(securityEventListener);
133 return processOutMessage(outputStream, encoding, outboundSecurityContext);
134 }
135
136
137
138
139
140
141
142
143
144 public XMLStreamWriter processOutMessage(
145 XMLStreamWriter xmlStreamWriter, String encoding, List<SecurityEvent> requestSecurityEvents,
146 SecurityEventListener securityEventListener) throws WSSecurityException {
147 final OutboundSecurityContextImpl outboundSecurityContext = new OutboundSecurityContextImpl();
148 outboundSecurityContext.putList(SecurityEvent.class, requestSecurityEvents);
149 outboundSecurityContext.addSecurityEventListener(securityEventListener);
150 return processOutMessage((Object) xmlStreamWriter, encoding, outboundSecurityContext);
151 }
152
153
154
155
156
157
158
159
160
161 public XMLStreamWriter processOutMessage(
162 XMLStreamWriter xmlStreamWriter, String encoding, OutboundSecurityContext outbounSecurityContext)
163 throws WSSecurityException {
164 return processOutMessage((Object) xmlStreamWriter, encoding, outbounSecurityContext);
165 }
166
167 public XMLStreamWriter processOutMessage(
168 Object output, String encoding, OutboundSecurityContext outboundSecurityContext
169 ) throws WSSecurityException {
170
171 final DocumentContextImpl documentContext = new DocumentContextImpl();
172 documentContext.setEncoding(encoding);
173
174 OutputProcessorChainImpl outputProcessorChain = new OutputProcessorChainImpl(outboundSecurityContext, documentContext);
175
176 try {
177 final SecurityHeaderOutputProcessor securityHeaderOutputProcessor = new SecurityHeaderOutputProcessor();
178 initializeOutputProcessor(outputProcessorChain, securityHeaderOutputProcessor, null, -1);
179
180 ConfiguredAction configuredAction = configureActions(outputProcessorChain);
181
182
183 if (configuredAction.signatureAction) {
184 setupSignatureKey(outputProcessorChain, securityProperties, configuredAction.signedSAML);
185 }
186 if (configuredAction.encryptionAction) {
187 setupEncryptionKey(outputProcessorChain, securityProperties);
188 }
189 if (configuredAction.kerberos) {
190 setupKerberosKey(outputProcessorChain, securityProperties,
191 configuredAction.signatureKerberos, configuredAction.encryptionKerberos);
192 }
193 if (configuredAction.derivedSignature) {
194 String id =
195 outputProcessorChain.getSecurityContext().get(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_SIGNATURE);
196 setDerivedIdentifier(outputProcessorChain, id);
197 }
198 if (configuredAction.derivedEncryption) {
199 String id =
200 outputProcessorChain.getSecurityContext().get(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTED_KEY);
201 if (id == null) {
202
203 id = outputProcessorChain.getSecurityContext().get(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION);
204 }
205 setDerivedIdentifier(outputProcessorChain, id);
206 }
207
208 final SecurityHeaderReorderProcessor securityHeaderReorderProcessor = new SecurityHeaderReorderProcessor();
209 initializeOutputProcessor(outputProcessorChain, securityHeaderReorderProcessor, null, -1);
210
211 if (output instanceof OutputStream) {
212 final FinalOutputProcessor finalOutputProcessor = new FinalOutputProcessor((OutputStream) output, encoding);
213 initializeOutputProcessor(outputProcessorChain, finalOutputProcessor, null, -1);
214
215 } else if (output instanceof XMLStreamWriter) {
216 final FinalOutputProcessor finalOutputProcessor = new FinalOutputProcessor((XMLStreamWriter) output);
217 initializeOutputProcessor(outputProcessorChain, finalOutputProcessor, null, -1);
218
219 } else {
220 throw new IllegalArgumentException(output + " is not supported as output");
221 }
222 } catch (XMLSecurityException e) {
223 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
224 }
225 return new XMLSecurityStreamWriter(outputProcessorChain);
226 }
227
228 private void initializeOutputProcessor(
229 OutputProcessorChainImpl outputProcessorChain, OutputProcessor outputProcessor,
230 XMLSecurityConstants.Action action, int actionOrder) throws XMLSecurityException {
231 if (actionOrder > -1) {
232 outputProcessor.addAfterProcessor(TimestampOutputProcessor.class);
233 outputProcessor.addAfterProcessor(UsernameTokenOutputProcessor.class);
234 outputProcessor.addAfterProcessor(SignatureConfirmationOutputProcessor.class);
235 outputProcessor.addAfterProcessor(CustomTokenOutputProcessor.class);
236 outputProcessor.addAfterProcessor(BinarySecurityTokenOutputProcessor.class);
237 outputProcessor.addAfterProcessor(SAMLTokenOutputProcessor.class);
238 }
239 outputProcessor.setXMLSecurityProperties(securityProperties);
240 outputProcessor.setAction(action, actionOrder);
241 outputProcessor.init(outputProcessorChain);
242 }
243
244 private void setupSignatureKey(
245 OutputProcessorChainImpl outputProcessorChain,
246 WSSSecurityProperties securityProperties,
247 boolean signedSAML
248 ) throws XMLSecurityException {
249 final String signatureAlgorithm = securityProperties.getSignatureAlgorithm();
250
251 GenericOutboundSecurityToken securityToken =
252 getOutboundSecurityToken(outputProcessorChain, WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_SIGNATURE);
253
254
255 if (securityToken != null && signatureAlgorithm != null) {
256 if (signatureAlgorithm.contains("hmac-sha")
257 && securityToken.getSecretKey(signatureAlgorithm) != null) {
258 return;
259 } else if (!signatureAlgorithm.contains("hmac-sha") && securityToken.getX509Certificates() != null) {
260 if (securityToken.getSecretKey(signatureAlgorithm) != null) {
261 return;
262 } else {
263
264 Key key =
265 securityProperties.getSignatureCrypto().getPrivateKey(
266 securityToken.getX509Certificates()[0], securityProperties.getCallbackHandler()
267 );
268 securityToken.setSecretKey(signatureAlgorithm, key);
269 return;
270 }
271 }
272 }
273
274
275 String alias = securityProperties.getSignatureUser();
276 WSPasswordCallback pwCb = new WSPasswordCallback(alias, WSPasswordCallback.SIGNATURE);
277 WSSUtils.doPasswordCallback(securityProperties.getCallbackHandler(), pwCb);
278
279 String password = pwCb.getPassword();
280 byte[] secretKey = pwCb.getKey();
281 Key key = null;
282 X509Certificate[] x509Certificates = null;
283 try {
284 if (password != null && securityProperties.getSignatureCrypto() != null) {
285 key = securityProperties.getSignatureCrypto().getPrivateKey(alias, password);
286 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
287 cryptoType.setAlias(alias);
288 x509Certificates = securityProperties.getSignatureCrypto().getX509Certificates(cryptoType);
289 if (x509Certificates == null || x509Certificates.length == 0) {
290 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, "noUserCertsFound",
291 new Object[] {alias});
292 }
293 } else if (secretKey != null) {
294 x509Certificates = null;
295 String algoFamily = JCEAlgorithmMapper.getJCEKeyAlgorithmFromURI(signatureAlgorithm);
296 key = new SecretKeySpec(secretKey, algoFamily);
297 } else {
298 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, "noPassword",
299 new Object[] {alias});
300 }
301 } catch (WSSecurityException ex) {
302 if (signedSAML && securityProperties.getSamlCallbackHandler() != null) {
303
304 return;
305 }
306 throw ex;
307 }
308
309
310 final String id = IDGenerator.generateID(null);
311 final GenericOutboundSecurityToken binarySecurityToken =
312 new GenericOutboundSecurityToken(id, WSSecurityTokenConstants.X509V3Token, key, x509Certificates);
313
314
315 final SecurityTokenProvider<OutboundSecurityToken> binarySecurityTokenProvider =
316 new SecurityTokenProvider<OutboundSecurityToken>() {
317
318 @Override
319 public OutboundSecurityToken getSecurityToken() throws WSSecurityException {
320 return binarySecurityToken;
321 }
322
323 @Override
324 public String getId() {
325 return id;
326 }
327 };
328
329 outputProcessorChain.getSecurityContext().registerSecurityTokenProvider(id, binarySecurityTokenProvider);
330 outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_SIGNATURE, id);
331 }
332
333 private void setupEncryptionKey(
334 OutputProcessorChainImpl outputProcessorChain,
335 WSSSecurityProperties securityProperties
336 ) throws XMLSecurityException {
337 final String symmetricEncryptionAlgorithm = securityProperties.getEncryptionSymAlgorithm();
338
339
340 GenericOutboundSecurityToken securityToken =
341 getOutboundSecurityToken(outputProcessorChain, WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION);
342 if (securityToken == null || securityToken.getSecretKey(symmetricEncryptionAlgorithm) == null) {
343
344 String keyAlgorithm = JCEAlgorithmMapper.getJCEKeyAlgorithmFromURI(securityProperties.getEncryptionSymAlgorithm());
345 KeyGenerator keyGen;
346 try {
347 keyGen = KeyGenerator.getInstance(keyAlgorithm);
348 } catch (NoSuchAlgorithmException e) {
349 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
350 }
351
352
353 if (keyAlgorithm.contains("AES")) {
354 int keyLength = JCEAlgorithmMapper.getKeyLengthFromURI(securityProperties.getEncryptionSymAlgorithm());
355 keyGen.init(keyLength);
356 }
357
358 final Key symmetricKey = keyGen.generateKey();
359 final String symmId = IDGenerator.generateID(null);
360
361 final GenericOutboundSecurityToken symmetricSecurityToken =
362 new GenericOutboundSecurityToken(symmId, WSSecurityTokenConstants.EncryptedKeyToken, symmetricKey);
363 securityToken = symmetricSecurityToken;
364 final SecurityTokenProvider<OutboundSecurityToken> securityTokenProvider =
365 new SecurityTokenProvider<OutboundSecurityToken>() {
366
367 @Override
368 public OutboundSecurityToken getSecurityToken() throws XMLSecurityException {
369 return symmetricSecurityToken;
370 }
371
372 @Override
373 public String getId() {
374 return symmId;
375 }
376 };
377
378 outputProcessorChain.getSecurityContext().registerSecurityTokenProvider(symmId, securityTokenProvider);
379 outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION, symmId);
380 }
381
382 if (!securityProperties.isEncryptSymmetricEncryptionKey()) {
383
384 return;
385 }
386
387
388 X509Certificate[] x509Certificates = null;
389 PublicKey publicKey = null;
390 if (securityProperties.isUseReqSigCertForEncryption()) {
391 X509Certificate x509Certificate = getReqSigCert(outputProcessorChain.getSecurityContext());
392 if (x509Certificate == null) {
393 publicKey = getReqSigPublicKey(outputProcessorChain.getSecurityContext());
394 if (publicKey == null) {
395 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, "noCert");
396 }
397 } else {
398 x509Certificates = new X509Certificate[1];
399 x509Certificates[0] = x509Certificate;
400 }
401 } else if (securityProperties.getEncryptionUseThisCertificate() != null) {
402 x509Certificates = new X509Certificate[1];
403 x509Certificates[0] = securityProperties.getEncryptionUseThisCertificate();
404 } else {
405 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
406 cryptoType.setAlias(securityProperties.getEncryptionUser());
407 Crypto crypto = securityProperties.getEncryptionCrypto();
408 x509Certificates = crypto.getX509Certificates(cryptoType);
409 if (x509Certificates == null || x509Certificates.length == 0) {
410 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, "noUserCertsFound",
411 new Object[] {securityProperties.getEncryptionUser(), "encryption"});
412 }
413 }
414
415
416 if (securityProperties.isEnableRevocation() && x509Certificates != null) {
417 Crypto crypto = securityProperties.getEncryptionCrypto();
418 crypto.verifyTrust(x509Certificates, true, null, null);
419 }
420
421
422 final String id = IDGenerator.generateID(null);
423 final GenericOutboundSecurityToken encryptedKeyToken =
424 new GenericOutboundSecurityToken(id, WSSecurityTokenConstants.X509V3Token, publicKey, x509Certificates);
425
426 encryptedKeyToken.addWrappedToken(securityToken);
427 securityToken.setKeyWrappingToken(encryptedKeyToken);
428
429
430 final SecurityTokenProvider<OutboundSecurityToken> encryptedKeyTokenProvider =
431 new SecurityTokenProvider<OutboundSecurityToken>() {
432
433 @Override
434 public OutboundSecurityToken getSecurityToken() throws WSSecurityException {
435 return encryptedKeyToken;
436 }
437
438 @Override
439 public String getId() {
440 return id;
441 }
442 };
443
444 outputProcessorChain.getSecurityContext().registerSecurityTokenProvider(id, encryptedKeyTokenProvider);
445 outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTED_KEY, id);
446 }
447
448 private void setupKerberosKey(
449 OutputProcessorChainImpl outputProcessorChain,
450 WSSSecurityProperties securityProperties,
451 boolean signature,
452 boolean encryption
453 ) throws XMLSecurityException {
454 GenericOutboundSecurityToken securityToken =
455 getOutboundSecurityToken(outputProcessorChain, WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_KERBEROS);
456 String kerberosId = null;
457
458 if (securityToken == null) {
459
460 final String id = IDGenerator.generateID(null);
461 kerberosId = id;
462 final KerberosClientSecurityToken kerberosClientSecurityToken =
463 new KerberosClientSecurityToken(
464 securityProperties.getCallbackHandler(), id
465 );
466
467 final SecurityTokenProvider<OutboundSecurityToken> kerberosSecurityTokenProvider =
468 new SecurityTokenProvider<OutboundSecurityToken>() {
469
470 @Override
471 public OutboundSecurityToken getSecurityToken() throws WSSecurityException {
472 return kerberosClientSecurityToken;
473 }
474
475 @Override
476 public String getId() {
477 return id;
478 }
479 };
480
481 outputProcessorChain.getSecurityContext().registerSecurityTokenProvider(id, kerberosSecurityTokenProvider);
482 outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_KERBEROS, id);
483 } else {
484 kerberosId = securityToken.getId();
485 }
486
487 if (signature) {
488 outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_SIGNATURE, kerberosId);
489 }
490 if (encryption) {
491 outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION, kerberosId);
492 }
493
494 }
495
496
497 private GenericOutboundSecurityToken getOutboundSecurityToken(
498 OutputProcessorChainImpl outputProcessorChain, String id
499 ) throws XMLSecurityException {
500 String tokenId =
501 outputProcessorChain.getSecurityContext().get(id);
502 SecurityTokenProvider<OutboundSecurityToken> signatureTokenProvider = null;
503 if (tokenId != null) {
504 signatureTokenProvider =
505 outputProcessorChain.getSecurityContext().getSecurityTokenProvider(tokenId);
506 if (signatureTokenProvider != null) {
507 return (GenericOutboundSecurityToken)signatureTokenProvider.getSecurityToken();
508 }
509 }
510
511 return null;
512 }
513
514 private X509Certificate getReqSigCert(SecurityContext securityContext) throws XMLSecurityException {
515 List<SecurityEvent> securityEventList = securityContext.getAsList(SecurityEvent.class);
516 if (securityEventList != null) {
517 for (int i = 0; i < securityEventList.size(); i++) {
518 SecurityEvent securityEvent = securityEventList.get(i);
519 if (securityEvent instanceof TokenSecurityEvent) {
520 @SuppressWarnings("unchecked")
521 TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent
522 = (TokenSecurityEvent<? extends SecurityToken>) securityEvent;
523 TokenUsage mainSig = WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE;
524 if (!tokenSecurityEvent.getSecurityToken().getTokenUsages().contains(mainSig)) {
525 continue;
526 }
527 X509Certificate[] x509Certificates = tokenSecurityEvent.getSecurityToken().getX509Certificates();
528 if (x509Certificates != null && x509Certificates.length > 0) {
529 return x509Certificates[0];
530 }
531 }
532 }
533 }
534 return null;
535 }
536
537 private PublicKey getReqSigPublicKey(SecurityContext securityContext) throws XMLSecurityException {
538 List<SecurityEvent> securityEventList = securityContext.getAsList(SecurityEvent.class);
539 if (securityEventList != null) {
540 for (int i = 0; i < securityEventList.size(); i++) {
541 SecurityEvent securityEvent = securityEventList.get(i);
542 if (securityEvent instanceof TokenSecurityEvent) {
543 @SuppressWarnings("unchecked")
544 TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent
545 = (TokenSecurityEvent<? extends SecurityToken>) securityEvent;
546 TokenUsage mainSig = WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE;
547 if (!tokenSecurityEvent.getSecurityToken().getTokenUsages().contains(mainSig)) {
548 continue;
549 }
550 PublicKey publicKey = tokenSecurityEvent.getSecurityToken().getPublicKey();
551 if (publicKey != null) {
552 return publicKey;
553 }
554 }
555 }
556 }
557 return null;
558 }
559
560 private void setDerivedIdentifier(OutputProcessorChainImpl outputProcessorChain, String id) {
561 WSSConstants.DerivedKeyTokenReference derivedKeyTokenReference = securityProperties.getDerivedKeyTokenReference();
562 switch (derivedKeyTokenReference) {
563
564 case DirectReference:
565 outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_DERIVED_KEY, id);
566 break;
567 case EncryptedKey:
568 String symmId = outputProcessorChain.getSecurityContext().get(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION);
569 outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_DERIVED_KEY, symmId);
570 outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTED_KEY, id);
571 break;
572 case SecurityContextToken:
573 outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_SECURITYCONTEXTTOKEN, id);
574 break;
575 }
576 }
577
578 private ConfiguredAction configureActions(OutputProcessorChainImpl outputProcessorChain) throws XMLSecurityException {
579 ConfiguredAction configuredAction = new ConfiguredAction();
580
581
582
583
584
585
586 boolean derivedSignatureButNotDerivedEncryption = false;
587 if (securityProperties.getDerivedKeyTokenReference() == WSSConstants.DerivedKeyTokenReference.EncryptedKey) {
588 for (XMLSecurityConstants.Action action : securityProperties.getActions()) {
589 if (WSSConstants.SIGNATURE_WITH_DERIVED_KEY.equals(action)) {
590 derivedSignatureButNotDerivedEncryption = true;
591 } else if (WSSConstants.ENCRYPTION_WITH_DERIVED_KEY.equals(action)) {
592 derivedSignatureButNotDerivedEncryption = false;
593 break;
594 }
595 }
596 }
597
598 int actionOrder = -1;
599 for (XMLSecurityConstants.Action action : securityProperties.getActions()) {
600 if (WSSConstants.TIMESTAMP.equals(action)) {
601 final TimestampOutputProcessor timestampOutputProcessor = new TimestampOutputProcessor();
602 initializeOutputProcessor(outputProcessorChain, timestampOutputProcessor, action, -1);
603 } else if (WSSConstants.SIGNATURE.equals(action)) {
604 configuredAction.signatureAction = true;
605 final BinarySecurityTokenOutputProcessor binarySecurityTokenOutputProcessor =
606 new BinarySecurityTokenOutputProcessor();
607 initializeOutputProcessor(outputProcessorChain, binarySecurityTokenOutputProcessor, action, -1);
608
609 final WSSSignatureOutputProcessor signatureOutputProcessor = new WSSSignatureOutputProcessor();
610 initializeOutputProcessor(outputProcessorChain, signatureOutputProcessor, action, ++actionOrder);
611
612 } else if (WSSConstants.ENCRYPTION.equals(action)) {
613 configuredAction.encryptionAction = true;
614 EncryptedKeyOutputProcessor encryptedKeyOutputProcessor = null;
615 ++actionOrder;
616 if (securityProperties.isEncryptSymmetricEncryptionKey()) {
617 final BinarySecurityTokenOutputProcessor binarySecurityTokenOutputProcessor =
618 new BinarySecurityTokenOutputProcessor();
619 initializeOutputProcessor(outputProcessorChain, binarySecurityTokenOutputProcessor, action, -1);
620
621 encryptedKeyOutputProcessor = new EncryptedKeyOutputProcessor();
622 initializeOutputProcessor(outputProcessorChain, encryptedKeyOutputProcessor, action, actionOrder);
623 }
624
625 final EncryptOutputProcessor encryptOutputProcessor = new EncryptOutputProcessor();
626 initializeOutputProcessor(outputProcessorChain, encryptOutputProcessor, action, actionOrder);
627
628 if (encryptedKeyOutputProcessor == null) {
629 final ReferenceListOutputProcessor referenceListOutputProcessor = new ReferenceListOutputProcessor();
630 referenceListOutputProcessor.addAfterProcessor(EncryptEndingOutputProcessor.class);
631 initializeOutputProcessor(outputProcessorChain, referenceListOutputProcessor, action, actionOrder);
632 }
633
634 } else if (WSSConstants.USERNAMETOKEN.equals(action)) {
635 final UsernameTokenOutputProcessor usernameTokenOutputProcessor = new UsernameTokenOutputProcessor();
636 initializeOutputProcessor(outputProcessorChain, usernameTokenOutputProcessor, action, -1);
637 } else if (WSSConstants.USERNAMETOKEN_SIGNED.equals(action)) {
638 final UsernameTokenOutputProcessor usernameTokenOutputProcessor = new UsernameTokenOutputProcessor();
639 initializeOutputProcessor(outputProcessorChain, usernameTokenOutputProcessor, action, -1);
640
641 final WSSSignatureOutputProcessor signatureOutputProcessor = new WSSSignatureOutputProcessor();
642 initializeOutputProcessor(outputProcessorChain, signatureOutputProcessor, action, ++actionOrder);
643
644 } else if (WSSConstants.SIGNATURE_CONFIRMATION.equals(action)) {
645 final SignatureConfirmationOutputProcessor signatureConfirmationOutputProcessor =
646 new SignatureConfirmationOutputProcessor();
647 initializeOutputProcessor(outputProcessorChain, signatureConfirmationOutputProcessor, action, -1);
648
649 } else if (WSSConstants.SIGNATURE_WITH_DERIVED_KEY.equals(action)) {
650 ++actionOrder;
651 if (securityProperties.getDerivedKeyTokenReference() == WSSConstants.DerivedKeyTokenReference.EncryptedKey) {
652 if (derivedSignatureButNotDerivedEncryption) {
653 final EncryptedKeyOutputProcessor encryptedKeyOutputProcessor = new EncryptedKeyOutputProcessor();
654 initializeOutputProcessor(outputProcessorChain, encryptedKeyOutputProcessor, action, actionOrder);
655 }
656 configuredAction.encryptionAction = true;
657 configuredAction.derivedEncryption = true;
658 } else if (securityProperties.getDerivedKeyTokenReference()
659 == WSSConstants.DerivedKeyTokenReference.SecurityContextToken) {
660 final SecurityContextTokenOutputProcessor securityContextTokenOutputProcessor =
661 new SecurityContextTokenOutputProcessor();
662 initializeOutputProcessor(outputProcessorChain, securityContextTokenOutputProcessor, action, -1);
663 configuredAction.signatureAction = true;
664 configuredAction.derivedSignature = true;
665 } else {
666 configuredAction.signatureAction = true;
667 configuredAction.derivedSignature = true;
668 }
669
670 final DerivedKeyTokenOutputProcessor derivedKeyTokenOutputProcessor = new DerivedKeyTokenOutputProcessor();
671 initializeOutputProcessor(outputProcessorChain, derivedKeyTokenOutputProcessor, action, -1);
672
673 final WSSSignatureOutputProcessor signatureOutputProcessor = new WSSSignatureOutputProcessor();
674 initializeOutputProcessor(outputProcessorChain, signatureOutputProcessor, action, actionOrder);
675
676 } else if (WSSConstants.ENCRYPTION_WITH_DERIVED_KEY.equals(action)) {
677 configuredAction.encryptionAction = true;
678 configuredAction.derivedEncryption = true;
679
680 EncryptedKeyOutputProcessor encryptedKeyOutputProcessor = null;
681
682 ++actionOrder;
683 if (securityProperties.getDerivedKeyTokenReference() == WSSConstants.DerivedKeyTokenReference.EncryptedKey) {
684 encryptedKeyOutputProcessor = new EncryptedKeyOutputProcessor();
685 initializeOutputProcessor(outputProcessorChain, encryptedKeyOutputProcessor, action, actionOrder);
686
687 } else if (securityProperties.getDerivedKeyTokenReference()
688 == WSSConstants.DerivedKeyTokenReference.SecurityContextToken) {
689 final SecurityContextTokenOutputProcessor securityContextTokenOutputProcessor =
690 new SecurityContextTokenOutputProcessor();
691 initializeOutputProcessor(outputProcessorChain, securityContextTokenOutputProcessor, action, actionOrder);
692 }
693 final DerivedKeyTokenOutputProcessor derivedKeyTokenOutputProcessor = new DerivedKeyTokenOutputProcessor();
694 initializeOutputProcessor(outputProcessorChain, derivedKeyTokenOutputProcessor, action, actionOrder);
695
696 final EncryptOutputProcessor encryptOutputProcessor = new EncryptOutputProcessor();
697 initializeOutputProcessor(outputProcessorChain, encryptOutputProcessor, action, actionOrder);
698
699 if (encryptedKeyOutputProcessor == null) {
700 final ReferenceListOutputProcessor referenceListOutputProcessor = new ReferenceListOutputProcessor();
701 referenceListOutputProcessor.addAfterProcessor(EncryptEndingOutputProcessor.class);
702 initializeOutputProcessor(outputProcessorChain, referenceListOutputProcessor, action, actionOrder);
703 }
704 } else if (WSSConstants.SAML_TOKEN_SIGNED.equals(action)) {
705 configuredAction.signatureAction = true;
706 configuredAction.signedSAML = true;
707 final BinarySecurityTokenOutputProcessor binarySecurityTokenOutputProcessor =
708 new BinarySecurityTokenOutputProcessor();
709 initializeOutputProcessor(outputProcessorChain, binarySecurityTokenOutputProcessor, action, -1);
710
711 final SAMLTokenOutputProcessor samlTokenOutputProcessor = new SAMLTokenOutputProcessor();
712 initializeOutputProcessor(outputProcessorChain, samlTokenOutputProcessor, action, -1);
713
714 final WSSSignatureOutputProcessor signatureOutputProcessor = new WSSSignatureOutputProcessor();
715 initializeOutputProcessor(outputProcessorChain, signatureOutputProcessor, action, ++actionOrder);
716
717 if (securityProperties.getDocumentCreator() == null) {
718 try {
719 securityProperties.setDocumentCreator(new DocumentCreatorImpl());
720 } catch (ParserConfigurationException e) {
721 throw new XMLSecurityException(e);
722 }
723 }
724
725 } else if (WSSConstants.SAML_TOKEN_UNSIGNED.equals(action)) {
726 final SAMLTokenOutputProcessor samlTokenOutputProcessor = new SAMLTokenOutputProcessor();
727 initializeOutputProcessor(outputProcessorChain, samlTokenOutputProcessor, action, -1);
728
729 if (securityProperties.getDocumentCreator() == null) {
730 try {
731 securityProperties.setDocumentCreator(new DocumentCreatorImpl());
732 } catch (ParserConfigurationException e) {
733 throw new XMLSecurityException(e);
734 }
735 }
736 } else if (WSSConstants.SIGNATURE_WITH_KERBEROS_TOKEN.equals(action)) {
737 configuredAction.kerberos = true;
738 configuredAction.signatureKerberos = true;
739 final BinarySecurityTokenOutputProcessor kerberosTokenOutputProcessor =
740 new BinarySecurityTokenOutputProcessor();
741 initializeOutputProcessor(outputProcessorChain, kerberosTokenOutputProcessor, action, -1);
742
743 final WSSSignatureOutputProcessor signatureOutputProcessor = new WSSSignatureOutputProcessor();
744 initializeOutputProcessor(outputProcessorChain, signatureOutputProcessor, action, ++actionOrder);
745 } else if (WSSConstants.ENCRYPTION_WITH_KERBEROS_TOKEN.equals(action)) {
746 configuredAction.kerberos = true;
747 configuredAction.encryptionKerberos = true;
748 final BinarySecurityTokenOutputProcessor kerberosTokenOutputProcessor =
749 new BinarySecurityTokenOutputProcessor();
750 initializeOutputProcessor(outputProcessorChain, kerberosTokenOutputProcessor, action, -1);
751
752 final EncryptOutputProcessor encryptOutputProcessor = new EncryptOutputProcessor();
753 initializeOutputProcessor(outputProcessorChain, encryptOutputProcessor, action, ++actionOrder);
754 } else if (WSSConstants.KERBEROS_TOKEN.equals(action)) {
755 configuredAction.kerberos = true;
756 final BinarySecurityTokenOutputProcessor kerberosTokenOutputProcessor =
757 new BinarySecurityTokenOutputProcessor();
758 initializeOutputProcessor(outputProcessorChain, kerberosTokenOutputProcessor, action, -1);
759 } else if (WSSConstants.CUSTOM_TOKEN.equals(action)) {
760 final CustomTokenOutputProcessor unknownTokenOutputProcessor =
761 new CustomTokenOutputProcessor();
762 initializeOutputProcessor(outputProcessorChain, unknownTokenOutputProcessor, action, -1);
763 }
764 }
765
766 return configuredAction;
767 }
768
769 private static final class ConfiguredAction {
770 boolean signatureAction = false;
771 boolean encryptionAction = false;
772 boolean signedSAML = false;
773 boolean kerberos = false;
774 boolean signatureKerberos = false;
775 boolean encryptionKerberos = false;
776 boolean derivedSignature = false;
777 boolean derivedEncryption = false;
778 }
779 }