1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.ws.security.components.crypto;
21
22 import java.security.PublicKey;
23 import java.security.cert.X509Certificate;
24 import java.security.interfaces.DSAPublicKey;
25 import java.security.interfaces.RSAPublicKey;
26 import java.util.Set;
27
28 import javax.xml.crypto.dsig.Reference;
29 import javax.xml.crypto.dsig.Transform;
30 import javax.xml.crypto.dsig.XMLSignature;
31
32 import org.apache.ws.security.WSSecurityException;
33
34
35
36
37 public class AlgorithmSuiteValidator {
38
39 private static final org.apache.commons.logging.Log LOG =
40 org.apache.commons.logging.LogFactory.getLog(AlgorithmSuiteValidator.class);
41
42 private final AlgorithmSuite algorithmSuite;
43
44 public AlgorithmSuiteValidator(
45 AlgorithmSuite algorithmSuite
46 ) {
47 this.algorithmSuite = algorithmSuite;
48 }
49
50
51
52
53 public void checkSignatureMethod(
54 String signatureMethod
55 ) throws WSSecurityException {
56 Set<String> allowedSignatureMethods = algorithmSuite.getSignatureMethods();
57 if (!allowedSignatureMethods.isEmpty()
58 && !allowedSignatureMethods.contains(signatureMethod)) {
59 LOG.debug(
60 "SignatureMethod " + signatureMethod + " does not match required values"
61 );
62 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY);
63 }
64 }
65
66
67
68
69 public void checkC14nAlgorithm(
70 String c14nAlgorithm
71 ) throws WSSecurityException {
72 Set<String> allowedC14nAlgorithms = algorithmSuite.getC14nAlgorithms();
73 if (!allowedC14nAlgorithms.isEmpty() && !allowedC14nAlgorithms.contains(c14nAlgorithm)) {
74 LOG.debug(
75 "C14nMethod " + c14nAlgorithm + " does not match required value"
76 );
77 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY);
78 }
79 }
80
81
82
83
84 public void checkSignatureAlgorithms(
85 XMLSignature xmlSignature
86 ) throws WSSecurityException {
87
88 String signatureMethod =
89 xmlSignature.getSignedInfo().getSignatureMethod().getAlgorithm();
90 checkSignatureMethod(signatureMethod);
91
92
93 String c14nMethod =
94 xmlSignature.getSignedInfo().getCanonicalizationMethod().getAlgorithm();
95 checkC14nAlgorithm(c14nMethod);
96
97 for (Object refObject : xmlSignature.getSignedInfo().getReferences()) {
98 Reference reference = (Reference)refObject;
99
100 String digestMethod = reference.getDigestMethod().getAlgorithm();
101 Set<String> allowedDigestAlgorithms = algorithmSuite.getDigestAlgorithms();
102 if (!allowedDigestAlgorithms.isEmpty()
103 && !allowedDigestAlgorithms.contains(digestMethod)) {
104 LOG.debug(
105 "DigestMethod " + digestMethod + " does not match required value"
106 );
107 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY);
108 }
109
110
111 for (int i = 0; i < reference.getTransforms().size(); i++) {
112 Transform transform = (Transform)reference.getTransforms().get(i);
113 String algorithm = transform.getAlgorithm();
114 Set<String> allowedTransformAlgorithms =
115 algorithmSuite.getTransformAlgorithms();
116 if (!allowedTransformAlgorithms.isEmpty()
117 && !allowedTransformAlgorithms.contains(algorithm)) {
118 LOG.debug(
119 "Transform method " + algorithm + " does not match required value"
120 );
121 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY);
122 }
123 }
124 }
125 }
126
127 public void checkEncryptionKeyWrapAlgorithm(
128 String keyWrapAlgorithm
129 ) throws WSSecurityException {
130 Set<String> keyWrapAlgorithms = algorithmSuite.getKeyWrapAlgorithms();
131 if (!keyWrapAlgorithms.isEmpty()
132 && !keyWrapAlgorithms.contains(keyWrapAlgorithm)) {
133 LOG.debug(
134 "The Key transport method does not match the requirement"
135 );
136 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY);
137 }
138 }
139
140 public void checkSymmetricEncryptionAlgorithm(
141 String symmetricAlgorithm
142 ) throws WSSecurityException {
143 Set<String> encryptionMethods = algorithmSuite.getEncryptionMethods();
144 if (!encryptionMethods.isEmpty()
145 && !encryptionMethods.contains(symmetricAlgorithm)) {
146 LOG.debug(
147 "The encryption algorithm does not match the requirement"
148 );
149 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY);
150 }
151 }
152
153
154
155
156 public void checkAsymmetricKeyLength(
157 X509Certificate x509Certificate
158 ) throws WSSecurityException {
159 if (x509Certificate == null) {
160 return;
161 }
162
163 checkAsymmetricKeyLength(x509Certificate.getPublicKey());
164 }
165
166
167
168
169 public void checkAsymmetricKeyLength(
170 PublicKey publicKey
171 ) throws WSSecurityException {
172 if (publicKey == null) {
173 return;
174 }
175 if (publicKey instanceof RSAPublicKey) {
176 int modulus = ((RSAPublicKey)publicKey).getModulus().bitLength();
177 if (modulus < algorithmSuite.getMinimumAsymmetricKeyLength()
178 || modulus > algorithmSuite.getMaximumAsymmetricKeyLength()) {
179 LOG.debug(
180 "The asymmetric key length does not match the requirement"
181 );
182 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY);
183 }
184 } else if (publicKey instanceof DSAPublicKey) {
185 int length = ((DSAPublicKey)publicKey).getParams().getP().bitLength();
186 if (length < algorithmSuite.getMinimumAsymmetricKeyLength()
187 || length > algorithmSuite.getMaximumAsymmetricKeyLength()) {
188 LOG.debug(
189 "The asymmetric key length does not match the requirement"
190 );
191 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY);
192 }
193 } else {
194 LOG.debug(
195 "An unknown public key was provided"
196 );
197 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY);
198 }
199 }
200
201
202
203
204 public void checkSymmetricKeyLength(
205 int secretKeyLength
206 ) throws WSSecurityException {
207 if (secretKeyLength < (algorithmSuite.getMinimumSymmetricKeyLength() / 8)
208 || secretKeyLength > (algorithmSuite.getMaximumSymmetricKeyLength() / 8)) {
209 LOG.debug(
210 "The symmetric key length does not match the requirement"
211 );
212 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY);
213 }
214 }
215
216
217
218
219 public void checkSignatureDerivedKeyLength(
220 int derivedKeyLength
221 ) throws WSSecurityException {
222 int requiredKeyLength = algorithmSuite.getSignatureDerivedKeyLength();
223 if (requiredKeyLength > 0 && (derivedKeyLength / 8) != requiredKeyLength) {
224 LOG.debug(
225 "The signature derived key length of " + derivedKeyLength + " does not match"
226 + "the requirement of " + requiredKeyLength
227 );
228 }
229 }
230
231
232
233
234 public void checkEncryptionDerivedKeyLength(
235 int derivedKeyLength
236 ) throws WSSecurityException {
237 int requiredKeyLength = algorithmSuite.getEncryptionDerivedKeyLength();
238 if (requiredKeyLength > 0 && (derivedKeyLength / 8) != requiredKeyLength) {
239 LOG.debug(
240 "The encryption derived key length of " + derivedKeyLength + " does not match"
241 + "the requirement of " + requiredKeyLength
242 );
243 }
244 }
245
246
247
248
249 public void checkDerivedKeyAlgorithm(
250 String algorithm
251 ) throws WSSecurityException {
252 Set<String> derivedKeyAlgorithms = algorithmSuite.getDerivedKeyAlgorithms();
253 if (!derivedKeyAlgorithms.isEmpty()
254 && !derivedKeyAlgorithms.contains(algorithm)) {
255 LOG.debug(
256 "The Derived Key Algorithm does not match the requirement"
257 );
258 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY);
259 }
260 }
261
262 }