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.model;
20  
21  import org.apache.neethi.Assertion;
22  import org.apache.neethi.Policy;
23  import org.apache.wss4j.policy.SPConstants;
24  
25  import java.util.*;
26  
27  import javax.xml.namespace.QName;
28  
29  public abstract class AbstractSymmetricAsymmetricBinding extends AbstractBinding {
30  
31      public enum ProtectionOrder {
32          EncryptBeforeSigning,
33          SignBeforeEncrypting;
34  
35          private static final Map<String, ProtectionOrder> LOOKUP = new HashMap<>();
36  
37          static {
38              for (ProtectionOrder u : EnumSet.allOf(ProtectionOrder.class)) {
39                  LOOKUP.put(u.name(), u);
40              }
41          }
42  
43          public static ProtectionOrder lookUp(String name) {
44              return LOOKUP.get(name);
45          }
46      }
47  
48      private ProtectionOrder protectionOrder = ProtectionOrder.SignBeforeEncrypting;
49      private boolean encryptSignature = false;
50      private boolean protectTokens = false;
51      private boolean onlySignEntireHeadersAndBody = false;
52  
53      protected AbstractSymmetricAsymmetricBinding(SPConstants.SPVersion version, Policy nestedPolicy) {
54          super(version, nestedPolicy);
55  
56          parseNestedSymmetricAsymmetricBindingBasePolicy(nestedPolicy, this);
57      }
58  
59      @Override
60      public boolean equals(Object object) {
61          if (object == this) {
62              return true;
63          }
64  
65          if (!(object instanceof AbstractSymmetricAsymmetricBinding)) {
66              return false;
67          }
68  
69          AbstractSymmetricAsymmetricBinding that = (AbstractSymmetricAsymmetricBinding)object;
70          if (protectionOrder != that.protectionOrder
71              || encryptSignature != that.encryptSignature
72              || protectTokens != that.protectTokens
73              || onlySignEntireHeadersAndBody != that.onlySignEntireHeadersAndBody) {
74              return false;
75          }
76  
77          return super.equals(object);
78      }
79  
80      @Override
81      public int hashCode() {
82          int result = 17;
83          if (protectionOrder != null) {
84              result = 31 * result + protectionOrder.hashCode();
85          }
86          result = 31 * result + Boolean.hashCode(encryptSignature);
87          result = 31 * result + Boolean.hashCode(protectTokens);
88          result = 31 * result + Boolean.hashCode(onlySignEntireHeadersAndBody);
89  
90          return 31 * result + super.hashCode();
91      }
92  
93      protected void parseNestedSymmetricAsymmetricBindingBasePolicy(
94          Policy nestedPolicy,  AbstractSymmetricAsymmetricBinding asymmetricBindingBase
95      ) {
96          Iterator<List<Assertion>> alternatives = nestedPolicy.getAlternatives();
97          //we just process the first alternative
98          //this means that if we have a compact policy only the first alternative is visible
99          //in contrary to a normalized policy where just one alternative exists
100         if (alternatives.hasNext()) {
101             List<Assertion> assertions = alternatives.next();
102             for (Assertion assertion : assertions) {
103                 String assertionName = assertion.getName().getLocalPart();
104                 String assertionNamespace = assertion.getName().getNamespaceURI();
105                 ProtectionOrder protectionOrder = ProtectionOrder.lookUp(assertionName);
106                 if (protectionOrder != null) {
107                     if (asymmetricBindingBase.getProtectionOrder() == ProtectionOrder.EncryptBeforeSigning) {
108                         throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
109                     }
110                     asymmetricBindingBase.setProtectionOrder(protectionOrder);
111                     continue;
112                 }
113 
114                 QName encryptSignature = getVersion().getSPConstants().getEncryptSignature();
115                 if (encryptSignature.getLocalPart().equals(assertionName)
116                     && encryptSignature.getNamespaceURI().equals(assertionNamespace)) {
117                     if (asymmetricBindingBase.isEncryptSignature()) {
118                         throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
119                     }
120                     asymmetricBindingBase.setEncryptSignature(true);
121                     continue;
122                 }
123 
124                 QName protectTokens = getVersion().getSPConstants().getProtectTokens();
125                 if (protectTokens.getLocalPart().equals(assertionName)
126                     && protectTokens.getNamespaceURI().equals(assertionNamespace)) {
127                     if (asymmetricBindingBase.isProtectTokens()) {
128                         throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
129                     }
130                     asymmetricBindingBase.setProtectTokens(true);
131                     continue;
132                 }
133 
134                 QName onlySign = getVersion().getSPConstants().getOnlySignEntireHeadersAndBody();
135                 if (onlySign.getLocalPart().equals(assertionName)
136                     && onlySign.getNamespaceURI().equals(assertionNamespace)) {
137                     if (asymmetricBindingBase.isOnlySignEntireHeadersAndBody()) {
138                         throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
139                     }
140                     asymmetricBindingBase.setOnlySignEntireHeadersAndBody(true);
141                     continue;
142                 }
143             }
144         }
145     }
146 
147     public ProtectionOrder getProtectionOrder() {
148         return protectionOrder;
149     }
150 
151     protected void setProtectionOrder(ProtectionOrder protectionOrder) {
152         this.protectionOrder = protectionOrder;
153     }
154 
155     public boolean isEncryptSignature() {
156         return encryptSignature;
157     }
158 
159     protected void setEncryptSignature(boolean encryptSignature) {
160         this.encryptSignature = encryptSignature;
161     }
162 
163     public boolean isProtectTokens() {
164         return protectTokens;
165     }
166 
167     protected void setProtectTokens(boolean protectTokens) {
168         this.protectTokens = protectTokens;
169     }
170 
171     public boolean isOnlySignEntireHeadersAndBody() {
172         return onlySignEntireHeadersAndBody;
173     }
174 
175     protected void setOnlySignEntireHeadersAndBody(boolean onlySignEntireHeadersAndBody) {
176         this.onlySignEntireHeadersAndBody = onlySignEntireHeadersAndBody;
177     }
178 }