View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.wss4j.policy.stax.assertionStates;
20  
21  import org.apache.wss4j.policy.AssertionState;
22  import org.apache.wss4j.common.WSSPolicyException;
23  import org.apache.wss4j.policy.model.AbstractSecurityAssertion;
24  import org.apache.wss4j.policy.model.EncryptedParts;
25  import org.apache.wss4j.policy.model.Header;
26  import org.apache.xml.security.stax.securityEvent.SecurityEvent;
27  import org.apache.xml.security.stax.securityEvent.SecurityEventConstants;
28  import org.apache.wss4j.policy.stax.Assertable;
29  import org.apache.wss4j.policy.stax.DummyPolicyAsserter;
30  import org.apache.wss4j.policy.stax.PolicyAsserter;
31  import org.apache.wss4j.stax.ext.WSSConstants;
32  import org.apache.wss4j.stax.securityEvent.EncryptedPartSecurityEvent;
33  import org.apache.wss4j.stax.securityEvent.WSSecurityEventConstants;
34  import org.apache.wss4j.stax.utils.WSSUtils;
35  
36  import javax.xml.namespace.QName;
37  
38  import java.util.LinkedList;
39  import java.util.List;
40  
41  /**
42   * WSP1.3, 4.2.1 EncryptedParts Assertion
43   */
44  public class EncryptedPartsAssertionState extends AssertionState implements Assertable {
45  
46      private int attachmentCount;
47      private int encryptedAttachmentCount;
48      private boolean encryptedAttachmentRequired;
49      private PolicyAsserter policyAsserter;
50      private final boolean soap12;
51  
52      public EncryptedPartsAssertionState(
53          AbstractSecurityAssertion assertion,
54          PolicyAsserter policyAsserter,
55          boolean asserted, int attachmentCount, boolean soap12) {
56          super(assertion, asserted);
57          this.attachmentCount = attachmentCount;
58  
59          this.policyAsserter = policyAsserter;
60          if (this.policyAsserter == null) {
61              this.policyAsserter = new DummyPolicyAsserter();
62          }
63  
64          if (asserted) {
65              policyAsserter.assertPolicy(getAssertion());
66          }
67  
68          this.soap12 = soap12;
69      }
70  
71      @Override
72      public SecurityEventConstants.Event[] getSecurityEventType() {
73          return new SecurityEventConstants.Event[]{
74                  WSSecurityEventConstants.ENCRYPTED_PART
75          };
76      }
77  
78      @Override
79      public boolean assertEvent(SecurityEvent securityEvent) throws WSSPolicyException {
80  
81          EncryptedPartSecurityEvent encryptedPartSecurityEvent = (EncryptedPartSecurityEvent) securityEvent;
82          EncryptedParts encryptedParts = (EncryptedParts) getAssertion();
83  
84          if (encryptedParts.getAttachments() != null) {
85              encryptedAttachmentRequired = true;
86              if (encryptedPartSecurityEvent.isAttachment()) {
87                  encryptedAttachmentCount++;
88                  setAsserted(true);
89                  policyAsserter.assertPolicy(getAssertion());
90                  return true;
91              }
92          }
93  
94          //we'll never get events with the exact body path but child elements so we can just check if we are in the body
95          if (encryptedParts.isBody() && WSSUtils.isInSOAPBody(encryptedPartSecurityEvent.getElementPath())) {
96              if (encryptedPartSecurityEvent.isEncrypted()) {
97                  setAsserted(true);
98                  policyAsserter.assertPolicy(getAssertion());
99                  return true;
100             } else {
101                 setAsserted(false);
102                 setErrorMessage("SOAP-Body must be encrypted");
103                 policyAsserter.unassertPolicy(getAssertion(), getErrorMessage());
104                 return false;
105             }
106         }
107         //body processed above. so this must be a header element
108         for (int i = 0; i < encryptedParts.getHeaders().size(); i++) {
109             Header header = encryptedParts.getHeaders().get(i);
110             QName headerQName = new QName(header.getNamespace(), header.getName() == null ? "" : header.getName());
111 
112             List<QName> headerPath = new LinkedList<>();
113             if (soap12) {
114                 headerPath.addAll(WSSConstants.SOAP_12_HEADER_PATH);
115             } else {
116                 headerPath.addAll(WSSConstants.SOAP_11_HEADER_PATH);
117             }
118             headerPath.add(headerQName);
119 
120             if (WSSUtils.pathMatches(headerPath, encryptedPartSecurityEvent.getElementPath(), header.getName() == null)) {
121                 if (encryptedPartSecurityEvent.isEncrypted()) {
122                     setAsserted(true);
123                     policyAsserter.assertPolicy(getAssertion());
124                     return true;
125                 } else {
126                     setAsserted(false);
127                     setErrorMessage("Element " + WSSUtils.pathAsString(encryptedPartSecurityEvent.getElementPath()) + " must be encrypted");
128                     policyAsserter.unassertPolicy(getAssertion(), getErrorMessage());
129                     return false;
130                 }
131             }
132         }
133 
134         //if we return false here other encrypted elements will trigger a PolicyViolationException
135         policyAsserter.assertPolicy(getAssertion());
136         return true;
137     }
138 
139     @Override
140     public boolean isAsserted() {
141         if (encryptedAttachmentRequired && encryptedAttachmentCount < attachmentCount) {
142             return false;
143         }
144         return super.isAsserted();
145     }
146 }