• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package sun.security.ssl;
27 
28 import java.security.AlgorithmConstraints;
29 import java.security.CryptoPrimitive;
30 import java.security.AlgorithmParameters;
31 
32 import javax.net.ssl.*;
33 
34 import java.security.Key;
35 
36 import java.util.Set;
37 import java.util.HashSet;
38 
39 import sun.security.util.DisabledAlgorithmConstraints;
40 import sun.security.ssl.CipherSuite.*;
41 
42 /**
43  * Algorithm constraints for disabled algorithms property
44  *
45  * See the "jdk.certpath.disabledAlgorithms" specification in java.security
46  * for the syntax of the disabled algorithm string.
47  */
48 final class SSLAlgorithmConstraints implements AlgorithmConstraints {
49     private final static AlgorithmConstraints tlsDisabledAlgConstraints =
50             new TLSDisabledAlgConstraints();
51     private final static AlgorithmConstraints x509DisabledAlgConstraints =
52             new X509DisabledAlgConstraints();
53     private AlgorithmConstraints userAlgConstraints = null;
54     private AlgorithmConstraints peerAlgConstraints = null;
55 
56     private boolean enabledX509DisabledAlgConstraints = true;
57 
SSLAlgorithmConstraints(AlgorithmConstraints algorithmConstraints)58     SSLAlgorithmConstraints(AlgorithmConstraints algorithmConstraints) {
59         userAlgConstraints = algorithmConstraints;
60     }
61 
SSLAlgorithmConstraints(SSLSocket socket, boolean withDefaultCertPathConstraints)62     SSLAlgorithmConstraints(SSLSocket socket,
63             boolean withDefaultCertPathConstraints) {
64         if (socket != null) {
65             userAlgConstraints =
66                 socket.getSSLParameters().getAlgorithmConstraints();
67         }
68 
69         if (!withDefaultCertPathConstraints) {
70             enabledX509DisabledAlgConstraints = false;
71         }
72     }
73 
SSLAlgorithmConstraints(SSLEngine engine, boolean withDefaultCertPathConstraints)74     SSLAlgorithmConstraints(SSLEngine engine,
75             boolean withDefaultCertPathConstraints) {
76         if (engine != null) {
77             userAlgConstraints =
78                 engine.getSSLParameters().getAlgorithmConstraints();
79         }
80 
81         if (!withDefaultCertPathConstraints) {
82             enabledX509DisabledAlgConstraints = false;
83         }
84     }
85 
SSLAlgorithmConstraints(SSLSocket socket, String[] supportedAlgorithms, boolean withDefaultCertPathConstraints)86     SSLAlgorithmConstraints(SSLSocket socket, String[] supportedAlgorithms,
87             boolean withDefaultCertPathConstraints) {
88         if (socket != null) {
89             userAlgConstraints =
90                 socket.getSSLParameters().getAlgorithmConstraints();
91             peerAlgConstraints =
92                 new SupportedSignatureAlgorithmConstraints(supportedAlgorithms);
93         }
94 
95         if (!withDefaultCertPathConstraints) {
96             enabledX509DisabledAlgConstraints = false;
97         }
98     }
99 
SSLAlgorithmConstraints(SSLEngine engine, String[] supportedAlgorithms, boolean withDefaultCertPathConstraints)100     SSLAlgorithmConstraints(SSLEngine engine, String[] supportedAlgorithms,
101             boolean withDefaultCertPathConstraints) {
102         if (engine != null) {
103             userAlgConstraints =
104                 engine.getSSLParameters().getAlgorithmConstraints();
105             peerAlgConstraints =
106                 new SupportedSignatureAlgorithmConstraints(supportedAlgorithms);
107         }
108 
109         if (!withDefaultCertPathConstraints) {
110             enabledX509DisabledAlgConstraints = false;
111         }
112     }
113 
permits(Set<CryptoPrimitive> primitives, String algorithm, AlgorithmParameters parameters)114     public boolean permits(Set<CryptoPrimitive> primitives,
115             String algorithm, AlgorithmParameters parameters) {
116 
117         boolean permitted = true;
118 
119         if (peerAlgConstraints != null) {
120             permitted = peerAlgConstraints.permits(
121                                     primitives, algorithm, parameters);
122         }
123 
124         if (permitted && userAlgConstraints != null) {
125             permitted = userAlgConstraints.permits(
126                                     primitives, algorithm, parameters);
127         }
128 
129         if (permitted) {
130             permitted = tlsDisabledAlgConstraints.permits(
131                                     primitives, algorithm, parameters);
132         }
133 
134         if (permitted && enabledX509DisabledAlgConstraints) {
135             permitted = x509DisabledAlgConstraints.permits(
136                                     primitives, algorithm, parameters);
137         }
138 
139         return permitted;
140     }
141 
permits(Set<CryptoPrimitive> primitives, Key key)142     public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
143 
144         boolean permitted = true;
145 
146         if (peerAlgConstraints != null) {
147             permitted = peerAlgConstraints.permits(primitives, key);
148         }
149 
150         if (permitted && userAlgConstraints != null) {
151             permitted = userAlgConstraints.permits(primitives, key);
152         }
153 
154         if (permitted) {
155             permitted = tlsDisabledAlgConstraints.permits(primitives, key);
156         }
157 
158         if (permitted && enabledX509DisabledAlgConstraints) {
159             permitted = x509DisabledAlgConstraints.permits(primitives, key);
160         }
161 
162         return permitted;
163     }
164 
permits(Set<CryptoPrimitive> primitives, String algorithm, Key key, AlgorithmParameters parameters)165     public boolean permits(Set<CryptoPrimitive> primitives,
166             String algorithm, Key key, AlgorithmParameters parameters) {
167 
168         boolean permitted = true;
169 
170         if (peerAlgConstraints != null) {
171             permitted = peerAlgConstraints.permits(
172                                     primitives, algorithm, key, parameters);
173         }
174 
175         if (permitted && userAlgConstraints != null) {
176             permitted = userAlgConstraints.permits(
177                                     primitives, algorithm, key, parameters);
178         }
179 
180         if (permitted) {
181             permitted = tlsDisabledAlgConstraints.permits(
182                                     primitives, algorithm, key, parameters);
183         }
184 
185         if (permitted && enabledX509DisabledAlgConstraints) {
186             permitted = x509DisabledAlgConstraints.permits(
187                                     primitives, algorithm, key, parameters);
188         }
189 
190         return permitted;
191     }
192 
193 
194     static private class SupportedSignatureAlgorithmConstraints
195                                     implements AlgorithmConstraints {
196         // supported signature algorithms
197         private String[] supportedAlgorithms;
198 
SupportedSignatureAlgorithmConstraints(String[] supportedAlgorithms)199         SupportedSignatureAlgorithmConstraints(String[] supportedAlgorithms) {
200             if (supportedAlgorithms != null) {
201                 this.supportedAlgorithms = supportedAlgorithms.clone();
202             } else {
203                 this.supportedAlgorithms = null;
204             }
205         }
206 
permits(Set<CryptoPrimitive> primitives, String algorithm, AlgorithmParameters parameters)207         public boolean permits(Set<CryptoPrimitive> primitives,
208                 String algorithm, AlgorithmParameters parameters) {
209 
210             if (algorithm == null || algorithm.length() == 0) {
211                 throw new IllegalArgumentException(
212                         "No algorithm name specified");
213             }
214 
215             if (primitives == null || primitives.isEmpty()) {
216                 throw new IllegalArgumentException(
217                         "No cryptographic primitive specified");
218             }
219 
220             if (supportedAlgorithms == null ||
221                         supportedAlgorithms.length == 0) {
222                 return false;
223             }
224 
225             // trim the MGF part: <digest>with<encryption>and<mgf>
226             int position = algorithm.indexOf("and");
227             if (position > 0) {
228                 algorithm = algorithm.substring(0, position);
229             }
230 
231             for (String supportedAlgorithm : supportedAlgorithms) {
232                 if (algorithm.equalsIgnoreCase(supportedAlgorithm)) {
233                     return true;
234                 }
235             }
236 
237             return false;
238         }
239 
permits(Set<CryptoPrimitive> primitives, Key key)240         final public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
241             return true;
242         }
243 
permits(Set<CryptoPrimitive> primitives, String algorithm, Key key, AlgorithmParameters parameters)244         final public boolean permits(Set<CryptoPrimitive> primitives,
245                 String algorithm, Key key, AlgorithmParameters parameters) {
246 
247             if (algorithm == null || algorithm.length() == 0) {
248                 throw new IllegalArgumentException(
249                         "No algorithm name specified");
250             }
251 
252             return permits(primitives, algorithm, parameters);
253         }
254     }
255 
256     static private class BasicDisabledAlgConstraints
257             extends DisabledAlgorithmConstraints {
BasicDisabledAlgConstraints(String propertyName)258         BasicDisabledAlgConstraints(String propertyName) {
259             super(propertyName);
260         }
261 
decomposes(KeyExchange keyExchange, boolean forCertPathOnly)262         protected Set<String> decomposes(KeyExchange keyExchange,
263                         boolean forCertPathOnly) {
264             Set<String> components = new HashSet<>();
265             switch (keyExchange) {
266                 case K_NULL:
267                     if (!forCertPathOnly) {
268                         components.add("NULL");
269                     }
270                     break;
271                 case K_RSA:
272                     components.add("RSA");
273                     break;
274                 case K_RSA_EXPORT:
275                     components.add("RSA");
276                     components.add("RSA_EXPORT");
277                     break;
278                 case K_DH_RSA:
279                     components.add("RSA");
280                     components.add("DH");
281                     components.add("DiffieHellman");
282                     components.add("DH_RSA");
283                     break;
284                 case K_DH_DSS:
285                     components.add("DSA");
286                     components.add("DSS");
287                     components.add("DH");
288                     components.add("DiffieHellman");
289                     components.add("DH_DSS");
290                     break;
291                 case K_DHE_DSS:
292                     components.add("DSA");
293                     components.add("DSS");
294                     components.add("DH");
295                     components.add("DHE");
296                     components.add("DiffieHellman");
297                     components.add("DHE_DSS");
298                     break;
299                 case K_DHE_RSA:
300                     components.add("RSA");
301                     components.add("DH");
302                     components.add("DHE");
303                     components.add("DiffieHellman");
304                     components.add("DHE_RSA");
305                     break;
306                 case K_DH_ANON:
307                     if (!forCertPathOnly) {
308                         components.add("ANON");
309                         components.add("DH");
310                         components.add("DiffieHellman");
311                         components.add("DH_ANON");
312                     }
313                     break;
314                 case K_ECDH_ECDSA:
315                     components.add("ECDH");
316                     components.add("ECDSA");
317                     components.add("ECDH_ECDSA");
318                     break;
319                 case K_ECDH_RSA:
320                     components.add("ECDH");
321                     components.add("RSA");
322                     components.add("ECDH_RSA");
323                     break;
324                 case K_ECDHE_ECDSA:
325                     components.add("ECDHE");
326                     components.add("ECDSA");
327                     components.add("ECDHE_ECDSA");
328                     break;
329                 case K_ECDHE_RSA:
330                     components.add("ECDHE");
331                     components.add("RSA");
332                     components.add("ECDHE_RSA");
333                     break;
334                 case K_ECDH_ANON:
335                     if (!forCertPathOnly) {
336                         components.add("ECDH");
337                         components.add("ANON");
338                         components.add("ECDH_ANON");
339                     }
340                     break;
341                 case K_KRB5:
342                     if (!forCertPathOnly) {
343                         components.add("KRB5");
344                     }
345                     break;
346                 case K_KRB5_EXPORT:
347                     if (!forCertPathOnly) {
348                         components.add("KRB5_EXPORT");
349                     }
350                     break;
351                 default:
352                     // ignore
353             }
354 
355             return components;
356         }
357 
decomposes(BulkCipher bulkCipher)358         protected Set<String> decomposes(BulkCipher bulkCipher) {
359             Set<String> components = new HashSet<>();
360 
361             if (bulkCipher.transformation != null) {
362                 components.addAll(super.decomposes(bulkCipher.transformation));
363             }
364 
365             return components;
366         }
367 
decomposes(MacAlg macAlg)368         protected Set<String> decomposes(MacAlg macAlg) {
369             Set<String> components = new HashSet<>();
370 
371             if (macAlg == CipherSuite.M_MD5) {
372                 components.add("MD5");
373                 components.add("HmacMD5");
374             } else if (macAlg == CipherSuite.M_SHA) {
375                 components.add("SHA1");
376                 components.add("SHA-1");
377                 components.add("HmacSHA1");
378             } else if (macAlg == CipherSuite.M_SHA256) {
379                 components.add("SHA256");
380                 components.add("SHA-256");
381                 components.add("HmacSHA256");
382             } else if (macAlg == CipherSuite.M_SHA384) {
383                 components.add("SHA384");
384                 components.add("SHA-384");
385                 components.add("HmacSHA384");
386             }
387 
388             return components;
389         }
390     }
391 
392     static private class TLSDisabledAlgConstraints
393             extends BasicDisabledAlgConstraints {
394 
TLSDisabledAlgConstraints()395         TLSDisabledAlgConstraints() {
396             super(DisabledAlgorithmConstraints.PROPERTY_TLS_DISABLED_ALGS);
397         }
398 
399         @Override
decomposes(String algorithm)400         protected Set<String> decomposes(String algorithm) {
401             if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) {
402                 CipherSuite cipherSuite = null;
403                 try {
404                     cipherSuite = CipherSuite.valueOf(algorithm);
405                 } catch (IllegalArgumentException iae) {
406                     // ignore: unknown or unsupported ciphersuite
407                 }
408 
409                 if (cipherSuite != null) {
410                     Set<String> components = new HashSet<>();
411 
412                     if(cipherSuite.keyExchange != null) {
413                         components.addAll(
414                             decomposes(cipherSuite.keyExchange, false));
415                     }
416 
417                     if (cipherSuite.cipher != null) {
418                         components.addAll(decomposes(cipherSuite.cipher));
419                     }
420 
421                     if (cipherSuite.macAlg != null) {
422                         components.addAll(decomposes(cipherSuite.macAlg));
423                     }
424 
425                     return components;
426                 }
427             }
428 
429             return super.decomposes(algorithm);
430         }
431     }
432 
433     static private class X509DisabledAlgConstraints
434             extends BasicDisabledAlgConstraints {
435 
X509DisabledAlgConstraints()436         X509DisabledAlgConstraints() {
437             super(DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
438         }
439 
440         @Override
decomposes(String algorithm)441         protected Set<String> decomposes(String algorithm) {
442             if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) {
443                 CipherSuite cipherSuite = null;
444                 try {
445                     cipherSuite = CipherSuite.valueOf(algorithm);
446                 } catch (IllegalArgumentException iae) {
447                     // ignore: unknown or unsupported ciphersuite
448                 }
449 
450                 if (cipherSuite != null) {
451                     Set<String> components = new HashSet<>();
452 
453                     if(cipherSuite.keyExchange != null) {
454                         components.addAll(
455                             decomposes(cipherSuite.keyExchange, true));
456                     }
457 
458                     // Certification path algorithm constraints do not apply
459                     // to cipherSuite.cipher and cipherSuite.macAlg.
460 
461                     return components;
462                 }
463             }
464 
465             return super.decomposes(algorithm);
466         }
467     }
468 }
469 
470