1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.stax.impl.processor.output;
20
21 import java.util.ArrayList;
22 import java.util.Deque;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import javax.xml.stream.XMLStreamConstants;
27 import javax.xml.stream.XMLStreamException;
28
29 import org.apache.wss4j.stax.ext.WSSConstants;
30 import org.apache.wss4j.stax.ext.WSSSecurityProperties;
31 import org.apache.wss4j.stax.impl.SecurityHeaderOrder;
32 import org.apache.wss4j.stax.utils.WSSUtils;
33 import org.apache.xml.security.exceptions.XMLSecurityException;
34 import org.apache.xml.security.stax.ext.OutputProcessorChain;
35 import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
36 import org.apache.xml.security.stax.impl.EncryptionPartDef;
37 import org.apache.xml.security.stax.impl.processor.output.AbstractEncryptEndingOutputProcessor;
38
39
40
41
42 public class EncryptEndingOutputProcessor extends AbstractEncryptEndingOutputProcessor {
43
44 public EncryptEndingOutputProcessor() throws XMLSecurityException {
45 super();
46 this.addAfterProcessor(EncryptOutputProcessor.class);
47 this.addAfterProcessor(UsernameTokenOutputProcessor.class);
48 }
49
50 @Override
51 public void processHeaderEvent(OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
52 OutputProcessorChain subOutputProcessorChain = outputProcessorChain.createSubChain(this);
53 if (attachmentCount(outputProcessorChain) > 0) {
54 WSSUtils.createEncryptedDataStructureForAttachments(this, subOutputProcessorChain);
55 }
56 }
57
58 @Override
59 public void flushBufferAndCallbackAfterHeader(OutputProcessorChain outputProcessorChain,
60 Deque<XMLSecEvent> xmlSecEventDeque)
61 throws XMLStreamException, XMLSecurityException {
62
63 final String actor = ((WSSSecurityProperties) getSecurityProperties()).getActor();
64
65
66 loop:
67 while (!xmlSecEventDeque.isEmpty()) {
68 XMLSecEvent xmlSecEvent = xmlSecEventDeque.pop();
69 if (XMLStreamConstants.START_ELEMENT == xmlSecEvent.getEventType()
70 && WSSUtils.isSecurityHeaderElement(xmlSecEvent, actor)) {
71 int attachmentCount = attachmentCount(outputProcessorChain);
72 for (int i = 0; i < attachmentCount; i++) {
73 OutputProcessorUtils.updateSecurityHeaderOrder(
74 outputProcessorChain, WSSConstants.TAG_xenc_EncryptedData, getAction(), true);
75 }
76 List<SecurityHeaderOrder> securityHeaderOrderList =
77 outputProcessorChain.getSecurityContext().getAsList(SecurityHeaderOrder.class);
78 List<SecurityHeaderOrder> tmpList = null;
79 if (securityHeaderOrderList != null) {
80 tmpList = new ArrayList<>(securityHeaderOrderList);
81 securityHeaderOrderList.clear();
82 }
83
84 outputProcessorChain.reset();
85 outputProcessorChain.processEvent(xmlSecEvent);
86
87 if (securityHeaderOrderList != null) {
88 securityHeaderOrderList.addAll(tmpList);
89 }
90 break loop;
91 }
92 outputProcessorChain.reset();
93 outputProcessorChain.processEvent(xmlSecEvent);
94 }
95 super.flushBufferAndCallbackAfterHeader(outputProcessorChain, xmlSecEventDeque);
96 }
97
98 private int attachmentCount(OutputProcessorChain outputProcessorChain) {
99 List<EncryptionPartDef> encryptionPartDefs =
100 outputProcessorChain.getSecurityContext().getAsList(EncryptionPartDef.class);
101 if (encryptionPartDefs == null) {
102 return 0;
103 }
104
105 int count = 0;
106 Iterator<EncryptionPartDef> encryptionPartDefIterator = encryptionPartDefs.iterator();
107 while (encryptionPartDefIterator.hasNext()) {
108 EncryptionPartDef encryptionPartDef = encryptionPartDefIterator.next();
109
110 if (encryptionPartDef.getCipherReferenceId() != null) {
111 count++;
112 }
113 }
114 return count;
115 }
116 }