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.neethi.PolicyComponent;
24  import org.apache.neethi.PolicyContainingAssertion;
25  import org.apache.wss4j.policy.SPConstants;
26  
27  import javax.xml.namespace.QName;
28  import javax.xml.stream.XMLStreamException;
29  import javax.xml.stream.XMLStreamWriter;
30  import java.util.*;
31  
32  public class AlgorithmSuite extends AbstractSecurityAssertion implements PolicyContainingAssertion {
33  
34      protected static final Map<String, AlgorithmSuiteType> ALGORITHM_SUITE_TYPES = new HashMap<>();
35  
36      private static final int MAX_SKL = 256;
37      private static final int MIN_AKL = 1024;
38      private static final int MAX_AKL = 4096;
39  
40      static {
41          ALGORITHM_SUITE_TYPES.put("Basic256", new AlgorithmSuiteType(
42                  "Basic256",
43                  SPConstants.SHA1,
44                  SPConstants.AES256,
45                  SPConstants.KW_AES256,
46                  SPConstants.KW_RSA_OAEP,
47                  SPConstants.P_SHA1_L256,
48                  SPConstants.P_SHA1_L192,
49                  256, 192, 256,
50                  MAX_SKL, MIN_AKL, MAX_AKL));
51          ALGORITHM_SUITE_TYPES.put("Basic192", new AlgorithmSuiteType(
52                  "Basic192",
53                  SPConstants.SHA1,
54                  SPConstants.AES192,
55                  SPConstants.KW_AES192,
56                  SPConstants.KW_RSA_OAEP,
57                  SPConstants.P_SHA1_L192,
58                  SPConstants.P_SHA1_L192,
59                  192, 192, 192,
60                  MAX_SKL, MIN_AKL, MAX_AKL));
61          ALGORITHM_SUITE_TYPES.put("Basic128", new AlgorithmSuiteType(
62                  "Basic128",
63                  SPConstants.SHA1,
64                  SPConstants.AES128,
65                  SPConstants.KW_AES128,
66                  SPConstants.KW_RSA_OAEP,
67                  SPConstants.P_SHA1_L128,
68                  SPConstants.P_SHA1_L128,
69                  128, 128, 128,
70                  MAX_SKL, MIN_AKL, MAX_AKL));
71          ALGORITHM_SUITE_TYPES.put("TripleDes", new AlgorithmSuiteType(
72                  "TripleDes",
73                  SPConstants.SHA1,
74                  SPConstants.TRIPLE_DES,
75                  SPConstants.KW_TRIPLE_DES,
76                  SPConstants.KW_RSA_OAEP,
77                  SPConstants.P_SHA1_L192,
78                  SPConstants.P_SHA1_L192,
79                  192, 192, 192,
80                  MAX_SKL, MIN_AKL, MAX_AKL));
81          ALGORITHM_SUITE_TYPES.put("Basic256Rsa15", new AlgorithmSuiteType(
82                  "Basic256Rsa15",
83                  SPConstants.SHA1,
84                  SPConstants.AES256,
85                  SPConstants.KW_AES256,
86                  SPConstants.KW_RSA15,
87                  SPConstants.P_SHA1_L256,
88                  SPConstants.P_SHA1_L192,
89                  256, 192, 256,
90                  MAX_SKL, MIN_AKL, MAX_AKL));
91          ALGORITHM_SUITE_TYPES.put("Basic192Rsa15", new AlgorithmSuiteType(
92                  "Basic192Rsa15",
93                  SPConstants.SHA1,
94                  SPConstants.AES192,
95                  SPConstants.KW_AES192,
96                  SPConstants.KW_RSA15,
97                  SPConstants.P_SHA1_L192,
98                  SPConstants.P_SHA1_L192,
99                  192, 192, 192,
100                 MAX_SKL, MIN_AKL, MAX_AKL));
101         ALGORITHM_SUITE_TYPES.put("Basic128Rsa15", new AlgorithmSuiteType(
102                 "Basic128Rsa15",
103                 SPConstants.SHA1,
104                 SPConstants.AES128,
105                 SPConstants.KW_AES128,
106                 SPConstants.KW_RSA15,
107                 SPConstants.P_SHA1_L128,
108                 SPConstants.P_SHA1_L128,
109                 128, 128, 128,
110                 MAX_SKL, MIN_AKL, MAX_AKL));
111         ALGORITHM_SUITE_TYPES.put("TripleDesRsa15", new AlgorithmSuiteType(
112                 "TripleDesRsa15",
113                 SPConstants.SHA1,
114                 SPConstants.TRIPLE_DES,
115                 SPConstants.KW_TRIPLE_DES,
116                 SPConstants.KW_RSA15,
117                 SPConstants.P_SHA1_L192,
118                 SPConstants.P_SHA1_L192,
119                 192, 192, 192,
120                 MAX_SKL, MIN_AKL, MAX_AKL));
121         ALGORITHM_SUITE_TYPES.put("Basic256Sha256", new AlgorithmSuiteType(
122                 "Basic256Sha256",
123                 SPConstants.SHA256,
124                 SPConstants.AES256,
125                 SPConstants.KW_AES256,
126                 SPConstants.KW_RSA_OAEP,
127                 SPConstants.P_SHA1_L256,
128                 SPConstants.P_SHA1_L192,
129                 256, 192, 256,
130                 MAX_SKL, MIN_AKL, MAX_AKL));
131         ALGORITHM_SUITE_TYPES.put("Basic192Sha256", new AlgorithmSuiteType(
132                 "Basic192Sha256",
133                 SPConstants.SHA256,
134                 SPConstants.AES192,
135                 SPConstants.KW_AES192,
136                 SPConstants.KW_RSA_OAEP,
137                 SPConstants.P_SHA1_L192,
138                 SPConstants.P_SHA1_L192,
139                 192, 192, 192,
140                 MAX_SKL, MIN_AKL, MAX_AKL));
141         ALGORITHM_SUITE_TYPES.put("Basic128Sha256", new AlgorithmSuiteType(
142                 "Basic128Sha256",
143                 SPConstants.SHA256,
144                 SPConstants.AES128,
145                 SPConstants.KW_AES128,
146                 SPConstants.KW_RSA_OAEP,
147                 SPConstants.P_SHA1_L128,
148                 SPConstants.P_SHA1_L128,
149                 128, 128, 128,
150                 MAX_SKL, MIN_AKL, MAX_AKL));
151         ALGORITHM_SUITE_TYPES.put("TripleDesSha256", new AlgorithmSuiteType(
152                 "TripleDesSha256",
153                 SPConstants.SHA256,
154                 SPConstants.TRIPLE_DES,
155                 SPConstants.KW_TRIPLE_DES,
156                 SPConstants.KW_RSA_OAEP,
157                 SPConstants.P_SHA1_L192,
158                 SPConstants.P_SHA1_L192,
159                 192, 192, 192,
160                 MAX_SKL, MIN_AKL, MAX_AKL));
161         ALGORITHM_SUITE_TYPES.put("Basic256Sha256Rsa15", new AlgorithmSuiteType(
162                 "Basic256Sha256Rsa15",
163                 SPConstants.SHA256,
164                 SPConstants.AES256,
165                 SPConstants.KW_AES256,
166                 SPConstants.KW_RSA15,
167                 SPConstants.P_SHA1_L256,
168                 SPConstants.P_SHA1_L192,
169                 256, 192, 256,
170                 MAX_SKL, MIN_AKL, MAX_AKL));
171         ALGORITHM_SUITE_TYPES.put("Basic192Sha256Rsa15", new AlgorithmSuiteType(
172                 "Basic192Sha256Rsa15",
173                 SPConstants.SHA256,
174                 SPConstants.AES192,
175                 SPConstants.KW_AES192,
176                 SPConstants.KW_RSA15,
177                 SPConstants.P_SHA1_L192,
178                 SPConstants.P_SHA1_L192,
179                 192, 192, 192,
180                 MAX_SKL, MIN_AKL, MAX_AKL));
181         ALGORITHM_SUITE_TYPES.put("Basic128Sha256Rsa15", new AlgorithmSuiteType(
182                 "Basic128Sha256Rsa15",
183                 SPConstants.SHA256,
184                 SPConstants.AES128,
185                 SPConstants.KW_AES128,
186                 SPConstants.KW_RSA15,
187                 SPConstants.P_SHA1_L128,
188                 SPConstants.P_SHA1_L128,
189                 128, 128, 128,
190                 MAX_SKL, MIN_AKL, MAX_AKL));
191         ALGORITHM_SUITE_TYPES.put("TripleDesSha256Rsa15", new AlgorithmSuiteType(
192                 "TripleDesSha256Rsa15",
193                 SPConstants.SHA256,
194                 SPConstants.TRIPLE_DES,
195                 SPConstants.KW_TRIPLE_DES,
196                 SPConstants.KW_RSA15,
197                 SPConstants.P_SHA1_L192,
198                 SPConstants.P_SHA1_L192,
199                 192, 192, 192,
200                 MAX_SKL, MIN_AKL, MAX_AKL));
201     }
202 
203     public static final class AlgorithmSuiteType {
204 
205         private String name;
206         private String digest;
207         private String encryption;
208         private String symmetricKeyWrap;
209         private String asymmetricKeyWrap;
210         private String encryptionKeyDerivation;
211         private String signatureKeyDerivation;
212         private int encryptionDerivedKeyLength;
213         private int signatureDerivedKeyLength;
214         private int minimumSymmetricKeyLength;
215         private int maximumSymmetricKeyLength;
216         private int minimumAsymmetricKeyLength;
217         private int maximumAsymmetricKeyLength;
218         private String mgfAlgo;
219         private String ns;
220         private String encryptionDigest;
221         private String symmetricSignature = SPConstants.HMAC_SHA1;
222         private String asymmetricSignature = SPConstants.RSA_SHA1;
223 
224         public AlgorithmSuiteType(String name, String digest, String encryption, String symmetricKeyWrap, //NOPMD
225                                   String asymmetricKeyWrap, String encryptionKeyDerivation,
226                                   String signatureKeyDerivation, int encryptionDerivedKeyLength,
227                                   int signatureDerivedKeyLength, int minimumSymmetricKeyLength,
228                                   int maximumSymmetricKeyLength, int minimumAsymmetricKeyLength,
229                                   int maximumAsymmetricKeyLength) {
230             this(name, digest, encryption, symmetricKeyWrap, asymmetricKeyWrap, encryptionKeyDerivation,
231                  signatureKeyDerivation, SPConstants.HMAC_SHA1, SPConstants.RSA_SHA1, encryptionDerivedKeyLength,
232                  signatureDerivedKeyLength, minimumSymmetricKeyLength, maximumSymmetricKeyLength,
233                  minimumAsymmetricKeyLength, maximumAsymmetricKeyLength);
234         }
235 
236         public AlgorithmSuiteType(String name, String digest, String encryption, String symmetricKeyWrap, //NOPMD
237                                   String asymmetricKeyWrap, String encryptionKeyDerivation,
238                                   String signatureKeyDerivation, String symmetricSignature,
239                                   String asymmetricSignature, int encryptionDerivedKeyLength,
240                                   int signatureDerivedKeyLength, int minimumSymmetricKeyLength,
241                                   int maximumSymmetricKeyLength, int minimumAsymmetricKeyLength,
242                                   int maximumAsymmetricKeyLength) {
243             this.name = name;
244             this.digest = digest;
245             this.encryption = encryption;
246             this.symmetricKeyWrap = symmetricKeyWrap;
247             this.asymmetricKeyWrap = asymmetricKeyWrap;
248             this.encryptionKeyDerivation = encryptionKeyDerivation;
249             this.signatureKeyDerivation = signatureKeyDerivation;
250             this.symmetricSignature = symmetricSignature;
251             this.asymmetricSignature = asymmetricSignature;
252             this.encryptionDerivedKeyLength = encryptionDerivedKeyLength;
253             this.signatureDerivedKeyLength = signatureDerivedKeyLength;
254             this.minimumSymmetricKeyLength = minimumSymmetricKeyLength;
255             this.maximumSymmetricKeyLength = maximumSymmetricKeyLength;
256             this.minimumAsymmetricKeyLength = minimumAsymmetricKeyLength;
257             this.maximumAsymmetricKeyLength = maximumAsymmetricKeyLength;
258         }
259 
260         public AlgorithmSuiteType(AlgorithmSuiteType algorithmSuiteType) {
261             this.name = algorithmSuiteType.name;
262             this.digest = algorithmSuiteType.digest;
263             this.encryption = algorithmSuiteType.encryption;
264             this.symmetricKeyWrap = algorithmSuiteType.symmetricKeyWrap;
265             this.asymmetricKeyWrap = algorithmSuiteType.asymmetricKeyWrap;
266             this.encryptionKeyDerivation = algorithmSuiteType.encryptionKeyDerivation;
267             this.signatureKeyDerivation = algorithmSuiteType.signatureKeyDerivation;
268             this.symmetricSignature = algorithmSuiteType.symmetricSignature;
269             this.asymmetricSignature = algorithmSuiteType.asymmetricSignature;
270             this.encryptionDerivedKeyLength = algorithmSuiteType.encryptionDerivedKeyLength;
271             this.signatureDerivedKeyLength = algorithmSuiteType.signatureDerivedKeyLength;
272             this.minimumSymmetricKeyLength = algorithmSuiteType.minimumSymmetricKeyLength;
273             this.maximumSymmetricKeyLength = algorithmSuiteType.maximumSymmetricKeyLength;
274             this.minimumAsymmetricKeyLength = algorithmSuiteType.minimumAsymmetricKeyLength;
275             this.maximumAsymmetricKeyLength = algorithmSuiteType.maximumAsymmetricKeyLength;
276             this.mgfAlgo = algorithmSuiteType.mgfAlgo;
277         }
278 
279         @Override
280         public boolean equals(Object object) {
281             if (object == this) {
282                 return true;
283             }
284 
285             if (!(object instanceof AlgorithmSuiteType)) {
286                 return false;
287             }
288 
289             AlgorithmSuiteType that = (AlgorithmSuiteType)object;
290             if (name != null && !name.equals(that.name)
291                 || name == null && that.name != null) {
292                 return false;
293             }
294             if (digest != null && !digest.equals(that.digest)
295                 || digest == null && that.digest != null) {
296                 return false;
297             }
298             if (encryption != null && !encryption.equals(that.encryption)
299                 || encryption == null && that.encryption != null) {
300                 return false;
301             }
302             if (symmetricKeyWrap != null && !symmetricKeyWrap.equals(that.symmetricKeyWrap)
303                 || symmetricKeyWrap == null && that.symmetricKeyWrap != null) {
304                 return false;
305             }
306             if (asymmetricKeyWrap != null && !asymmetricKeyWrap.equals(that.asymmetricKeyWrap)
307                 || asymmetricKeyWrap == null && that.asymmetricKeyWrap != null) {
308                 return false;
309             }
310             if (encryptionKeyDerivation != null && !encryptionKeyDerivation.equals(that.encryptionKeyDerivation)
311                 || encryptionKeyDerivation == null && that.encryptionKeyDerivation != null) {
312                 return false;
313             }
314             if (signatureKeyDerivation != null && !signatureKeyDerivation.equals(that.signatureKeyDerivation)
315                 || signatureKeyDerivation == null && that.signatureKeyDerivation != null) {
316                 return false;
317             }
318             if (symmetricSignature != null && !symmetricSignature.equals(that.symmetricSignature)
319                 || symmetricSignature == null && that.symmetricSignature != null) {
320                 return false;
321             }
322             if (asymmetricSignature != null && !asymmetricSignature.equals(that.asymmetricSignature)
323                 || asymmetricSignature == null && that.asymmetricSignature != null) {
324                 return false;
325             }
326             if (ns != null && !ns.equals(that.ns)
327                 || ns == null && that.ns != null) {
328                 return false;
329             }
330             if (mgfAlgo != null && !mgfAlgo.equals(that.mgfAlgo)
331                 || mgfAlgo == null && that.mgfAlgo != null) {
332                 return false;
333             }
334             if (encryptionDigest != null && !encryptionDigest.equals(that.encryptionDigest)
335                 || encryptionDigest == null && that.encryptionDigest != null) {
336                 return false;
337             }
338 
339             return !(encryptionDerivedKeyLength != that.encryptionDerivedKeyLength
340                 || signatureDerivedKeyLength != that.signatureDerivedKeyLength
341                 || minimumSymmetricKeyLength != that.minimumSymmetricKeyLength
342                 || maximumSymmetricKeyLength != that.maximumSymmetricKeyLength
343                 || minimumAsymmetricKeyLength != that.minimumAsymmetricKeyLength
344                 || maximumAsymmetricKeyLength != that.maximumAsymmetricKeyLength);
345         }
346 
347         @Override
348         public int hashCode() {
349             int result = 17;
350             if (name != null) {
351                 result = 31 * result + name.hashCode();
352             }
353             if (digest != null) {
354                 result = 31 * result + digest.hashCode();
355             }
356             if (encryption != null) {
357                 result = 31 * result + encryption.hashCode();
358             }
359             if (symmetricKeyWrap != null) {
360                 result = 31 * result + symmetricKeyWrap.hashCode();
361             }
362             if (asymmetricKeyWrap != null) {
363                 result = 31 * result + asymmetricKeyWrap.hashCode();
364             }
365             if (encryptionKeyDerivation != null) {
366                 result = 31 * result + encryptionKeyDerivation.hashCode();
367             }
368             if (signatureKeyDerivation != null) {
369                 result = 31 * result + signatureKeyDerivation.hashCode();
370             }
371             if (symmetricSignature != null) {
372                 result = 31 * result + symmetricSignature.hashCode();
373             }
374             if (asymmetricSignature != null) {
375                 result = 31 * result + asymmetricSignature.hashCode();
376             }
377 
378             result = 31 * result + Integer.hashCode(encryptionDerivedKeyLength);
379             result = 31 * result + Integer.hashCode(signatureDerivedKeyLength);
380             result = 31 * result + Integer.hashCode(minimumSymmetricKeyLength);
381             result = 31 * result + Integer.hashCode(maximumSymmetricKeyLength);
382             result = 31 * result + Integer.hashCode(minimumAsymmetricKeyLength);
383             result = 31 * result + Integer.hashCode(maximumAsymmetricKeyLength);
384 
385             if (mgfAlgo != null) {
386                 result = 31 * result + mgfAlgo.hashCode();
387             }
388             if (ns != null) {
389                 result = 31 * result + ns.hashCode();
390             }
391             if (encryptionDigest != null) {
392                 result = 31 * result + encryptionDigest.hashCode();
393             }
394 
395             return 31 * result + super.hashCode();
396         }
397 
398         public String getName() {
399             return name;
400         }
401 
402         public String getDigest() {
403             return digest;
404         }
405 
406         public String getEncryption() {
407             return encryption;
408         }
409 
410         public String getSymmetricKeyWrap() {
411             return symmetricKeyWrap;
412         }
413 
414         public String getAsymmetricKeyWrap() {
415             return asymmetricKeyWrap;
416         }
417 
418         public String getEncryptionKeyDerivation() {
419             return encryptionKeyDerivation;
420         }
421 
422         public String getSignatureKeyDerivation() {
423             return signatureKeyDerivation;
424         }
425 
426         public String getSymmetricSignature() {
427             return symmetricSignature;
428         }
429 
430         public String getAsymmetricSignature() {
431             return asymmetricSignature;
432         }
433 
434         public void setSymmetricSignature(String symmetricSignature) {
435             this.symmetricSignature = symmetricSignature;
436         }
437 
438         public void setAsymmetricSignature(String asymmetricSignature) {
439             this.asymmetricSignature = asymmetricSignature;
440         }
441 
442         public int getEncryptionDerivedKeyLength() {
443             return encryptionDerivedKeyLength;
444         }
445 
446         public int getSignatureDerivedKeyLength() {
447             return signatureDerivedKeyLength;
448         }
449 
450         public int getMinimumSymmetricKeyLength() {
451             return minimumSymmetricKeyLength;
452         }
453 
454         public int getMaximumSymmetricKeyLength() {
455             return maximumSymmetricKeyLength;
456         }
457 
458         public int getMinimumAsymmetricKeyLength() {
459             return minimumAsymmetricKeyLength;
460         }
461 
462         public int getMaximumAsymmetricKeyLength() {
463             return maximumAsymmetricKeyLength;
464         }
465 
466         public void setNamespace(String ns) {
467             this.ns = ns;
468         }
469 
470         public String getNamespace() {
471             return ns;
472         }
473 
474         public void setMGFAlgo(String mgfAlgo) {
475             this.mgfAlgo = mgfAlgo;
476         }
477 
478         public String getMGFAlgo() {
479             return mgfAlgo;
480         }
481 
482         public void setEncryptionDigest(String encryptionDigest) {
483             this.encryptionDigest = encryptionDigest;
484         }
485 
486         public String getEncryptionDigest() {
487             return encryptionDigest;
488         }
489     }
490 
491     public enum XPathType {
492         XPathNone(null),
493         XPath10(SPConstants.XPATH),
494         XPathFilter20(SPConstants.XPATH20),
495         AbsXPath(SPConstants.ABS_XPATH);
496 
497         private static final Map<String, XPathType> LOOKUP = new HashMap<>();
498 
499         static {
500             for (XPathType u : EnumSet.allOf(XPathType.class)) {
501                 LOOKUP.put(u.name(), u);
502             }
503         }
504 
505         public static XPathType lookUp(String name) {
506             return LOOKUP.get(name);
507         }
508 
509         private String value;
510 
511         public String getValue() {
512             return value;
513         }
514 
515         XPathType(String value) {
516             this.value = value;
517         }
518     }
519 
520     public enum C14NType {
521         ExclusiveC14N(SPConstants.EX_C14N),
522         InclusiveC14N(SPConstants.C14N),
523         InclusiveC14N11(SPConstants.C14N11);
524 
525         private static final Map<String, C14NType> LOOKUP = new HashMap<>();
526 
527         static {
528             for (C14NType u : EnumSet.allOf(C14NType.class)) {
529                 LOOKUP.put(u.name(), u);
530             }
531         }
532 
533         private String value;
534 
535         public static C14NType lookUp(String name) {
536             return LOOKUP.get(name);
537         }
538 
539         public String getValue() {
540             return value;
541         }
542 
543         C14NType(String value) {
544             this.value = value;
545         }
546     }
547 
548     public enum SOAPNormType {
549         SOAPNormalizationNone(null),
550         SOAPNormalization10(SPConstants.SOAP_NORMALIZATION_10);
551 
552         private static final Map<String, SOAPNormType> LOOKUP = new HashMap<>();
553 
554         static {
555             for (SOAPNormType u : EnumSet.allOf(SOAPNormType.class)) {
556                 LOOKUP.put(u.name(), u);
557             }
558         }
559 
560         public static SOAPNormType lookUp(String name) {
561             return LOOKUP.get(name);
562         }
563 
564         private String value;
565 
566         public String getValue() {
567             return value;
568         }
569 
570         SOAPNormType(String value) {
571             this.value = value;
572         }
573     }
574 
575     public enum STRType {
576         STRTransformNone(null),
577         STRTransform10(SPConstants.STR_TRANSFORM_10);
578 
579         private static final Map<String, STRType> LOOKUP = new HashMap<>();
580 
581         static {
582             for (STRType u : EnumSet.allOf(STRType.class)) {
583                 LOOKUP.put(u.name(), u);
584             }
585         }
586 
587         public static STRType lookUp(String name) {
588             return LOOKUP.get(name);
589         }
590 
591         private String value;
592 
593         public String getValue() {
594             return value;
595         }
596 
597         STRType(String value) {
598             this.value = value;
599         }
600     }
601 
602     private Policy nestedPolicy;
603     private AlgorithmSuiteType algorithmSuiteType;
604     private C14NType c14n = C14NType.ExclusiveC14N;
605     private SOAPNormType soapNormType = SOAPNormType.SOAPNormalizationNone;
606     private STRType strType = STRType.STRTransformNone;
607     private XPathType xPathType = XPathType.XPathNone;
608 
609     private String computedKey = SPConstants.P_SHA1;
610     private String firstInvalidAlgorithmSuite;
611 
612     public AlgorithmSuite(SPConstants.SPVersion version, Policy nestedPolicy) {
613         super(version);
614         this.nestedPolicy = nestedPolicy;
615 
616         parseNestedPolicy(nestedPolicy, this);
617     }
618 
619     @Override
620     public Policy getPolicy() {
621         return nestedPolicy;
622     }
623 
624     @Override
625     public QName getName() {
626         return getVersion().getSPConstants().getAlgorithmSuite();
627     }
628 
629     @Override
630     public boolean equals(Object object) {
631         if (object == this) {
632             return true;
633         }
634 
635         if (!(object instanceof AlgorithmSuite)) {
636             return false;
637         }
638 
639         AlgorithmSuite that = (AlgorithmSuite)object;
640         if (c14n != that.c14n || soapNormType != that.soapNormType || strType != that.strType
641             || xPathType != that.xPathType) {
642             return false;
643         }
644 
645         if (algorithmSuiteType != null && !algorithmSuiteType.equals(that.algorithmSuiteType)
646             || algorithmSuiteType == null && that.algorithmSuiteType != null) {
647             return false;
648         }
649         if (computedKey != null && !computedKey.equals(that.computedKey)
650             || computedKey == null && that.computedKey != null) {
651             return false;
652         }
653 
654         return super.equals(object);
655     }
656 
657     @Override
658     public int hashCode() {
659         int result = 17;
660         if (c14n != null) {
661             result = 31 * result + c14n.hashCode();
662         }
663         if (soapNormType != null) {
664             result = 31 * result + soapNormType.hashCode();
665         }
666         if (strType != null) {
667             result = 31 * result + strType.hashCode();
668         }
669         if (xPathType != null) {
670             result = 31 * result + xPathType.hashCode();
671         }
672         if (algorithmSuiteType != null) {
673             result = 31 * result + algorithmSuiteType.hashCode();
674         }
675         if (computedKey != null) {
676             result = 31 * result + computedKey.hashCode();
677         }
678 
679         return 31 * result + super.hashCode();
680     }
681 
682     @Override
683     public PolicyComponent normalize() {
684         return super.normalize(getPolicy());
685     }
686 
687     @Override
688     public void serialize(XMLStreamWriter writer) throws XMLStreamException {
689         super.serialize(writer, getPolicy());
690     }
691 
692     @Override
693     protected AbstractSecurityAssertion cloneAssertion(Policy nestedPolicy) {
694         return new AlgorithmSuite(getVersion(), nestedPolicy);
695     }
696 
697     protected void parseNestedPolicy(Policy nestedPolicy, AlgorithmSuite algorithmSuite) {
698         Iterator<List<Assertion>> alternatives = nestedPolicy.getAlternatives();
699         //we just process the first alternative
700         //this means that if we have a compact policy only the first alternative is visible
701         //in contrary to a normalized policy where just one alternative exists
702         if (alternatives.hasNext()) {
703             List<Assertion> assertions = alternatives.next();
704             for (Assertion assertion : assertions) {
705                 String assertionName = assertion.getName().getLocalPart();
706                 String assertionNamespace = assertion.getName().getNamespaceURI();
707                 if (!getVersion().getNamespace().equals(assertionNamespace)) {
708                     parseCustomAssertion(assertion);
709                     continue;
710                 }
711                 AlgorithmSuiteType algorithmSuiteType = ALGORITHM_SUITE_TYPES.get(assertionName);
712                 if (algorithmSuiteType != null) {
713                     if (algorithmSuite.getAlgorithmSuiteType() != null) {
714                         throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
715                     }
716 
717                     // Clone so as not to change the namespace for other AlgorithmSuiteTypes...
718                     AlgorithmSuiteType newAlgorithmSuiteType = new AlgorithmSuiteType(algorithmSuiteType);
719                     newAlgorithmSuiteType.setNamespace(getVersion().getNamespace());
720                     algorithmSuite.setAlgorithmSuiteType(newAlgorithmSuiteType);
721                     continue;
722                 } else {
723                     firstInvalidAlgorithmSuite = assertionName;
724                 }
725                 C14NType c14NType = C14NType.lookUp(assertionName);
726                 if (c14NType != null) {
727                     algorithmSuite.setC14n(c14NType);
728                     continue;
729                 }
730                 SOAPNormType soapNormType = SOAPNormType.lookUp(assertionName);
731                 if (soapNormType != null) {
732                     if (algorithmSuite.getSoapNormType() == SOAPNormType.SOAPNormalization10) {
733                         throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
734                     }
735                     algorithmSuite.setSoapNormType(soapNormType);
736                     continue;
737                 }
738                 STRType strType = STRType.lookUp(assertionName);
739                 if (strType != null) {
740                     if (algorithmSuite.getStrType() == STRType.STRTransform10) {
741                         throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
742                     }
743                     algorithmSuite.setStrType(strType);
744                     continue;
745                 }
746                 XPathType xPathType = XPathType.lookUp(assertionName);
747                 if (xPathType != null) {
748                     if (algorithmSuite.getXPathType() != XPathType.XPathNone) {
749                         throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
750                     }
751                     algorithmSuite.setXPathType(xPathType);
752                     continue;
753                 }
754             }
755         }
756     }
757 
758     protected void parseCustomAssertion(Assertion assertion) {
759     }
760 
761     public AlgorithmSuiteType getAlgorithmSuiteType() {
762         return algorithmSuiteType;
763     }
764 
765     protected void setAlgorithmSuiteType(AlgorithmSuiteType algorithmSuiteType) {
766         this.algorithmSuiteType = algorithmSuiteType;
767     }
768 
769     public C14NType getC14n() {
770         return c14n;
771     }
772 
773     protected void setC14n(C14NType c14n) {
774         this.c14n = c14n;
775     }
776 
777     public SOAPNormType getSoapNormType() {
778         return soapNormType;
779     }
780 
781     protected void setSoapNormType(SOAPNormType soapNormType) {
782         this.soapNormType = soapNormType;
783     }
784 
785     public STRType getStrType() {
786         return strType;
787     }
788 
789     protected void setStrType(STRType strType) {
790         this.strType = strType;
791     }
792 
793     public XPathType getXPathType() {
794         return xPathType;
795     }
796 
797     protected void setXPathType(XPathType xPathType) {
798         this.xPathType = xPathType;
799     }
800 
801     public String getComputedKey() {
802         return computedKey;
803     }
804 
805     public static Collection<String> getSupportedAlgorithmSuiteNames() {
806         return ALGORITHM_SUITE_TYPES.keySet();
807     }
808 
809     public String getFirstInvalidAlgorithmSuite() {
810         return firstInvalidAlgorithmSuite;
811     }
812 
813 }
814