1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.policy.stax.assertionStates;
20
21 import org.apache.wss4j.policy.AssertionState;
22 import org.apache.wss4j.policy.SPConstants;
23 import org.apache.wss4j.common.WSSPolicyException;
24 import org.apache.wss4j.policy.model.AbstractSecurityAssertion;
25 import org.apache.wss4j.policy.model.AbstractSymmetricAsymmetricBinding;
26 import org.apache.wss4j.policy.stax.Assertable;
27 import org.apache.wss4j.policy.stax.DummyPolicyAsserter;
28 import org.apache.wss4j.policy.stax.PolicyAsserter;
29 import org.apache.wss4j.stax.securityEvent.*;
30 import org.apache.wss4j.stax.utils.WSSUtils;
31 import org.apache.xml.security.stax.ext.XMLSecurityConstants;
32 import org.apache.xml.security.stax.securityEvent.ContentEncryptedElementSecurityEvent;
33 import org.apache.xml.security.stax.securityEvent.EncryptedElementSecurityEvent;
34 import org.apache.xml.security.stax.securityEvent.SecurityEvent;
35 import org.apache.xml.security.stax.securityEvent.SecurityEventConstants;
36 import org.apache.xml.security.stax.securityEvent.SignedElementSecurityEvent;
37
38 import javax.xml.namespace.QName;
39
40 import java.util.List;
41
42
43
44
45
46 public class ProtectionOrderAssertionState extends AssertionState implements Assertable {
47
48 private PolicyAsserter policyAsserter;
49
50 public ProtectionOrderAssertionState(AbstractSecurityAssertion assertion,
51 PolicyAsserter policyAsserter,
52 boolean asserted) {
53 super(assertion, asserted);
54 this.policyAsserter = policyAsserter;
55 if (this.policyAsserter == null) {
56 this.policyAsserter = new DummyPolicyAsserter();
57 }
58
59 if (asserted) {
60 String namespace = getAssertion().getName().getNamespaceURI();
61 AbstractSymmetricAsymmetricBinding.ProtectionOrder protectionOrder =
62 ((AbstractSymmetricAsymmetricBinding) getAssertion()).getProtectionOrder();
63 switch (protectionOrder) {
64 case SignBeforeEncrypting:
65 policyAsserter.assertPolicy(new QName(namespace, SPConstants.SIGN_BEFORE_ENCRYPTING));
66 break;
67 case EncryptBeforeSigning:
68 policyAsserter.assertPolicy(new QName(namespace, SPConstants.ENCRYPT_BEFORE_SIGNING));
69 break;
70 }
71 }
72 }
73
74 @Override
75 public SecurityEventConstants.Event[] getSecurityEventType() {
76 return new SecurityEventConstants.Event[]{
77 SecurityEventConstants.SignedElement,
78 WSSecurityEventConstants.SIGNED_PART,
79 WSSecurityEventConstants.EncryptedElement,
80 WSSecurityEventConstants.ENCRYPTED_PART,
81 WSSecurityEventConstants.ContentEncrypted,
82 };
83 }
84
85 @Override
86 public boolean assertEvent(SecurityEvent securityEvent) throws WSSPolicyException {
87 AbstractSymmetricAsymmetricBinding.ProtectionOrder protectionOrder =
88 ((AbstractSymmetricAsymmetricBinding) getAssertion()).getProtectionOrder();
89 SecurityEventConstants.Event event = securityEvent.getSecurityEventType();
90 if (WSSecurityEventConstants.SignedElement.equals(event)) {
91 SignedElementSecurityEvent signedElementSecurityEvent = (SignedElementSecurityEvent) securityEvent;
92 if (!signedElementSecurityEvent.isSigned()) {
93 return true;
94 }
95 List<XMLSecurityConstants.ContentType> contentTypes = signedElementSecurityEvent.getProtectionOrder();
96 testProtectionOrder(protectionOrder, contentTypes, signedElementSecurityEvent.getElementPath());
97 } else if (WSSecurityEventConstants.SIGNED_PART.equals(event)) {
98 SignedPartSecurityEvent signedPartSecurityEvent = (SignedPartSecurityEvent) securityEvent;
99 if (!signedPartSecurityEvent.isSigned()) {
100 return true;
101 }
102 List<XMLSecurityConstants.ContentType> contentTypes = signedPartSecurityEvent.getProtectionOrder();
103 testProtectionOrder(protectionOrder, contentTypes, signedPartSecurityEvent.getElementPath());
104 } else if (WSSecurityEventConstants.EncryptedElement.equals(event)) {
105 EncryptedElementSecurityEvent encryptedElementSecurityEvent = (EncryptedElementSecurityEvent) securityEvent;
106 if (!encryptedElementSecurityEvent.isEncrypted()) {
107 return true;
108 }
109 List<XMLSecurityConstants.ContentType> contentTypes = encryptedElementSecurityEvent.getProtectionOrder();
110 testProtectionOrder(protectionOrder, contentTypes, encryptedElementSecurityEvent.getElementPath());
111 } else if (WSSecurityEventConstants.ENCRYPTED_PART.equals(event)) {
112 EncryptedPartSecurityEvent encryptedPartSecurityEvent = (EncryptedPartSecurityEvent) securityEvent;
113 if (!encryptedPartSecurityEvent.isEncrypted()) {
114 return true;
115 }
116 List<XMLSecurityConstants.ContentType> contentTypes = encryptedPartSecurityEvent.getProtectionOrder();
117 testProtectionOrder(protectionOrder, contentTypes, encryptedPartSecurityEvent.getElementPath());
118 } else if (WSSecurityEventConstants.ContentEncrypted.equals(event)) {
119 ContentEncryptedElementSecurityEvent contentEncryptedElementSecurityEvent =
120 (ContentEncryptedElementSecurityEvent) securityEvent;
121 if (!contentEncryptedElementSecurityEvent.isEncrypted()) {
122 return true;
123 }
124 List<XMLSecurityConstants.ContentType> contentTypes = contentEncryptedElementSecurityEvent.getProtectionOrder();
125 testProtectionOrder(protectionOrder, contentTypes, contentEncryptedElementSecurityEvent.getElementPath());
126 }
127 return isAsserted();
128 }
129
130 private void testProtectionOrder(AbstractSymmetricAsymmetricBinding.ProtectionOrder protectionOrder,
131 List<XMLSecurityConstants.ContentType> contentTypes, List<QName> elementPath) {
132 String namespace = getAssertion().getName().getNamespaceURI();
133
134 switch (protectionOrder) {
135 case SignBeforeEncrypting:
136 int lastSignature = contentTypes.lastIndexOf(XMLSecurityConstants.ContentType.SIGNATURE);
137 int firstEncryption = contentTypes.indexOf(XMLSecurityConstants.ContentType.ENCRYPTION);
138 if (firstEncryption >= 0 && firstEncryption < lastSignature) {
139 setAsserted(false);
140 setErrorMessage("Policy enforces " + protectionOrder + " but the " + WSSUtils.pathAsString(elementPath)
141 + " was encrypted and then signed");
142 policyAsserter.unassertPolicy(new QName(namespace, SPConstants.SIGN_BEFORE_ENCRYPTING),
143 getErrorMessage());
144 } else {
145 policyAsserter.assertPolicy(new QName(namespace, SPConstants.SIGN_BEFORE_ENCRYPTING));
146 }
147 break;
148 case EncryptBeforeSigning:
149 int lastEncryption = contentTypes.lastIndexOf(XMLSecurityConstants.ContentType.ENCRYPTION);
150 int firstSignature = contentTypes.indexOf(XMLSecurityConstants.ContentType.SIGNATURE);
151 if (firstSignature >= 0 && firstSignature < lastEncryption) {
152 setAsserted(false);
153 setErrorMessage("Policy enforces " + protectionOrder + " but the " + WSSUtils.pathAsString(elementPath)
154 + " was signed and then encrypted");
155 policyAsserter.unassertPolicy(new QName(namespace, SPConstants.ENCRYPT_BEFORE_SIGNING),
156 getErrorMessage());
157 } else {
158 policyAsserter.assertPolicy(new QName(namespace, SPConstants.ENCRYPT_BEFORE_SIGNING));
159 }
160 break;
161 }
162 }
163 }