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 void setDigest(String digest) {
407             this.digest = digest;
408         }
409 
410         public String getEncryption() {
411             return encryption;
412         }
413         
414         public void setEncryption(String encryption) {
415             this.encryption = encryption;
416         }
417 
418         public String getSymmetricKeyWrap() {
419             return symmetricKeyWrap;
420         }
421         
422         public void setSymmetricKeyWrap(String symmetricKeyWrap) {
423             this.symmetricKeyWrap = symmetricKeyWrap;
424         }
425 
426         public String getAsymmetricKeyWrap() {
427             return asymmetricKeyWrap;
428         }
429         
430         public void setAsymmetricKeyWrap(String asymmetricKeyWrap) {
431             this.asymmetricKeyWrap = asymmetricKeyWrap;
432         }
433 
434         public String getEncryptionKeyDerivation() {
435             return encryptionKeyDerivation;
436         }
437         
438         public void setEncryptionKeyDerivation(String encryptionKeyDerivation) {
439             this.encryptionKeyDerivation = encryptionKeyDerivation;
440         }
441 
442         public String getSignatureKeyDerivation() {
443             return signatureKeyDerivation;
444         }
445         
446         public void setSignatureKeyDerivation(String signatureKeyDerivation) {
447             this.signatureKeyDerivation = signatureKeyDerivation;
448         }
449 
450         public String getSymmetricSignature() {
451             return symmetricSignature;
452         }
453 
454         public String getAsymmetricSignature() {
455             return asymmetricSignature;
456         }
457 
458         public void setSymmetricSignature(String symmetricSignature) {
459             this.symmetricSignature = symmetricSignature;
460         }
461 
462         public void setAsymmetricSignature(String asymmetricSignature) {
463             this.asymmetricSignature = asymmetricSignature;
464         }
465 
466         public int getEncryptionDerivedKeyLength() {
467             return encryptionDerivedKeyLength;
468         }
469         
470         public void getEncryptionDerivedKeyLength(int encryptionDerivedKeyLength) {
471             this.encryptionDerivedKeyLength = encryptionDerivedKeyLength;
472         }
473 
474         public int getSignatureDerivedKeyLength() {
475             return signatureDerivedKeyLength;
476         }
477         
478         public void setSignatureDerivedKeyLength(int signatureDerivedKeyLength) {
479             this.signatureDerivedKeyLength = signatureDerivedKeyLength;
480         }
481 
482         public int getMinimumSymmetricKeyLength() {
483             return minimumSymmetricKeyLength;
484         }
485         
486         public void setMinimumSymmetricKeyLength(int minimumSymmetricKeyLength) {
487             this.minimumSymmetricKeyLength = minimumSymmetricKeyLength;
488         }
489 
490         public int getMaximumSymmetricKeyLength() {
491             return maximumSymmetricKeyLength;
492         }
493 
494         public void setMaximumSymmetricKeyLength(int maximumSymmetricKeyLength) {
495             this.maximumSymmetricKeyLength = maximumSymmetricKeyLength;
496         }
497         
498         public int getMinimumAsymmetricKeyLength() {
499             return minimumAsymmetricKeyLength;
500         }
501         
502         public void setMinimumAsymmetricKeyLength(int minimumAsymmetricKeyLength) {
503             this.minimumAsymmetricKeyLength = minimumAsymmetricKeyLength;
504         }
505 
506         public int getMaximumAsymmetricKeyLength() {
507             return maximumAsymmetricKeyLength;
508         }
509         
510         public void setMaximumAsymmetricKeyLength(int maximumAsymmetricKeyLength) {
511             this.maximumAsymmetricKeyLength = maximumAsymmetricKeyLength;
512         }
513 
514         public void setNamespace(String ns) {
515             this.ns = ns;
516         }
517 
518         public String getNamespace() {
519             return ns;
520         }
521 
522         public void setMGFAlgo(String mgfAlgo) {
523             this.mgfAlgo = mgfAlgo;
524         }
525 
526         public String getMGFAlgo() {
527             return mgfAlgo;
528         }
529 
530         public void setEncryptionDigest(String encryptionDigest) {
531             this.encryptionDigest = encryptionDigest;
532         }
533 
534         public String getEncryptionDigest() {
535             return encryptionDigest;
536         }
537     }
538 
539     public enum XPathType {
540         XPathNone(null),
541         XPath10(SPConstants.XPATH),
542         XPathFilter20(SPConstants.XPATH20),
543         AbsXPath(SPConstants.ABS_XPATH);
544 
545         private static final Map<String, XPathType> LOOKUP = new HashMap<>();
546 
547         static {
548             for (XPathType u : EnumSet.allOf(XPathType.class)) {
549                 LOOKUP.put(u.name(), u);
550             }
551         }
552 
553         public static XPathType lookUp(String name) {
554             return LOOKUP.get(name);
555         }
556 
557         private String value;
558 
559         public String getValue() {
560             return value;
561         }
562 
563         XPathType(String value) {
564             this.value = value;
565         }
566     }
567 
568     public enum C14NType {
569         ExclusiveC14N(SPConstants.EX_C14N),
570         InclusiveC14N(SPConstants.C14N),
571         InclusiveC14N11(SPConstants.C14N11);
572 
573         private static final Map<String, C14NType> LOOKUP = new HashMap<>();
574 
575         static {
576             for (C14NType u : EnumSet.allOf(C14NType.class)) {
577                 LOOKUP.put(u.name(), u);
578             }
579         }
580 
581         private String value;
582 
583         public static C14NType lookUp(String name) {
584             return LOOKUP.get(name);
585         }
586 
587         public String getValue() {
588             return value;
589         }
590 
591         C14NType(String value) {
592             this.value = value;
593         }
594     }
595 
596     public enum SOAPNormType {
597         SOAPNormalizationNone(null),
598         SOAPNormalization10(SPConstants.SOAP_NORMALIZATION_10);
599 
600         private static final Map<String, SOAPNormType> LOOKUP = new HashMap<>();
601 
602         static {
603             for (SOAPNormType u : EnumSet.allOf(SOAPNormType.class)) {
604                 LOOKUP.put(u.name(), u);
605             }
606         }
607 
608         public static SOAPNormType lookUp(String name) {
609             return LOOKUP.get(name);
610         }
611 
612         private String value;
613 
614         public String getValue() {
615             return value;
616         }
617 
618         SOAPNormType(String value) {
619             this.value = value;
620         }
621     }
622 
623     public enum STRType {
624         STRTransformNone(null),
625         STRTransform10(SPConstants.STR_TRANSFORM_10);
626 
627         private static final Map<String, STRType> LOOKUP = new HashMap<>();
628 
629         static {
630             for (STRType u : EnumSet.allOf(STRType.class)) {
631                 LOOKUP.put(u.name(), u);
632             }
633         }
634 
635         public static STRType lookUp(String name) {
636             return LOOKUP.get(name);
637         }
638 
639         private String value;
640 
641         public String getValue() {
642             return value;
643         }
644 
645         STRType(String value) {
646             this.value = value;
647         }
648     }
649 
650     private Policy nestedPolicy;
651     private AlgorithmSuiteType algorithmSuiteType;
652     private C14NType c14n = C14NType.ExclusiveC14N;
653     private SOAPNormType soapNormType = SOAPNormType.SOAPNormalizationNone;
654     private STRType strType = STRType.STRTransformNone;
655     private XPathType xPathType = XPathType.XPathNone;
656 
657     private String computedKey = SPConstants.P_SHA1;
658     private String firstInvalidAlgorithmSuite;
659 
660     public AlgorithmSuite(SPConstants.SPVersion version, Policy nestedPolicy) {
661         super(version);
662         this.nestedPolicy = nestedPolicy;
663 
664         parseNestedPolicy(nestedPolicy, this);
665     }
666 
667     @Override
668     public Policy getPolicy() {
669         return nestedPolicy;
670     }
671 
672     @Override
673     public QName getName() {
674         return getVersion().getSPConstants().getAlgorithmSuite();
675     }
676 
677     @Override
678     public boolean equals(Object object) {
679         if (object == this) {
680             return true;
681         }
682 
683         if (!(object instanceof AlgorithmSuite)) {
684             return false;
685         }
686 
687         AlgorithmSuite that = (AlgorithmSuite)object;
688         if (c14n != that.c14n || soapNormType != that.soapNormType || strType != that.strType
689             || xPathType != that.xPathType) {
690             return false;
691         }
692 
693         if (algorithmSuiteType != null && !algorithmSuiteType.equals(that.algorithmSuiteType)
694             || algorithmSuiteType == null && that.algorithmSuiteType != null) {
695             return false;
696         }
697         if (computedKey != null && !computedKey.equals(that.computedKey)
698             || computedKey == null && that.computedKey != null) {
699             return false;
700         }
701 
702         return super.equals(object);
703     }
704 
705     @Override
706     public int hashCode() {
707         int result = 17;
708         if (c14n != null) {
709             result = 31 * result + c14n.hashCode();
710         }
711         if (soapNormType != null) {
712             result = 31 * result + soapNormType.hashCode();
713         }
714         if (strType != null) {
715             result = 31 * result + strType.hashCode();
716         }
717         if (xPathType != null) {
718             result = 31 * result + xPathType.hashCode();
719         }
720         if (algorithmSuiteType != null) {
721             result = 31 * result + algorithmSuiteType.hashCode();
722         }
723         if (computedKey != null) {
724             result = 31 * result + computedKey.hashCode();
725         }
726 
727         return 31 * result + super.hashCode();
728     }
729 
730     @Override
731     public PolicyComponent normalize() {
732         return super.normalize(getPolicy());
733     }
734 
735     @Override
736     public void serialize(XMLStreamWriter writer) throws XMLStreamException {
737         super.serialize(writer, getPolicy());
738     }
739 
740     @Override
741     protected AbstractSecurityAssertion cloneAssertion(Policy nestedPolicy) {
742         return new AlgorithmSuite(getVersion(), nestedPolicy);
743     }
744 
745     protected void parseNestedPolicy(Policy nestedPolicy, AlgorithmSuite algorithmSuite) {
746         Iterator<List<Assertion>> alternatives = nestedPolicy.getAlternatives();
747         //we just process the first alternative
748         //this means that if we have a compact policy only the first alternative is visible
749         //in contrary to a normalized policy where just one alternative exists
750         if (alternatives.hasNext()) {
751             List<Assertion> assertions = alternatives.next();
752             for (Assertion assertion : assertions) {
753                 String assertionName = assertion.getName().getLocalPart();
754                 String assertionNamespace = assertion.getName().getNamespaceURI();
755                 if (!getVersion().getNamespace().equals(assertionNamespace)) {
756                     parseCustomAssertion(assertion);
757                     continue;
758                 }
759                 AlgorithmSuiteType algorithmSuiteType = ALGORITHM_SUITE_TYPES.get(assertionName);
760                 if (algorithmSuiteType != null) {
761                     if (algorithmSuite.getAlgorithmSuiteType() != null) {
762                         throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
763                     }
764 
765                     // Clone so as not to change the namespace for other AlgorithmSuiteTypes...
766                     AlgorithmSuiteType newAlgorithmSuiteType = new AlgorithmSuiteType(algorithmSuiteType);
767                     newAlgorithmSuiteType.setNamespace(getVersion().getNamespace());
768                     algorithmSuite.setAlgorithmSuiteType(newAlgorithmSuiteType);
769                     continue;
770                 } else {
771                     firstInvalidAlgorithmSuite = assertionName;
772                 }
773                 C14NType c14NType = C14NType.lookUp(assertionName);
774                 if (c14NType != null) {
775                     algorithmSuite.setC14n(c14NType);
776                     continue;
777                 }
778                 SOAPNormType soapNormType = SOAPNormType.lookUp(assertionName);
779                 if (soapNormType != null) {
780                     if (algorithmSuite.getSoapNormType() == SOAPNormType.SOAPNormalization10) {
781                         throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
782                     }
783                     algorithmSuite.setSoapNormType(soapNormType);
784                     continue;
785                 }
786                 STRType strType = STRType.lookUp(assertionName);
787                 if (strType != null) {
788                     if (algorithmSuite.getStrType() == STRType.STRTransform10) {
789                         throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
790                     }
791                     algorithmSuite.setStrType(strType);
792                     continue;
793                 }
794                 XPathType xPathType = XPathType.lookUp(assertionName);
795                 if (xPathType != null) {
796                     if (algorithmSuite.getXPathType() != XPathType.XPathNone) {
797                         throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
798                     }
799                     algorithmSuite.setXPathType(xPathType);
800                     continue;
801                 }
802             }
803         }
804     }
805 
806     protected void parseCustomAssertion(Assertion assertion) {
807     }
808 
809     public AlgorithmSuiteType getAlgorithmSuiteType() {
810         return algorithmSuiteType;
811     }
812 
813     protected void setAlgorithmSuiteType(AlgorithmSuiteType algorithmSuiteType) {
814         this.algorithmSuiteType = algorithmSuiteType;
815     }
816 
817     public C14NType getC14n() {
818         return c14n;
819     }
820 
821     protected void setC14n(C14NType c14n) {
822         this.c14n = c14n;
823     }
824 
825     public SOAPNormType getSoapNormType() {
826         return soapNormType;
827     }
828 
829     protected void setSoapNormType(SOAPNormType soapNormType) {
830         this.soapNormType = soapNormType;
831     }
832 
833     public STRType getStrType() {
834         return strType;
835     }
836 
837     protected void setStrType(STRType strType) {
838         this.strType = strType;
839     }
840 
841     public XPathType getXPathType() {
842         return xPathType;
843     }
844 
845     protected void setXPathType(XPathType xPathType) {
846         this.xPathType = xPathType;
847     }
848 
849     public String getComputedKey() {
850         return computedKey;
851     }
852 
853     public static Collection<String> getSupportedAlgorithmSuiteNames() {
854         return ALGORITHM_SUITE_TYPES.keySet();
855     }
856 
857     public String getFirstInvalidAlgorithmSuite() {
858         return firstInvalidAlgorithmSuite;
859     }
860 
861 }
862