|
1 /* |
|
2 * Copyright (c) 2015, 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.util.HashSet; |
|
29 import java.util.Set; |
|
30 import sun.security.util.AlgorithmDecomposer; |
|
31 import static sun.security.ssl.CipherSuite.*; |
|
32 import static sun.security.ssl.CipherSuite.KeyExchange.*; |
|
33 |
|
34 /** |
|
35 * The class decomposes standard SSL/TLS cipher suites into sub-elements. |
|
36 */ |
|
37 class SSLAlgorithmDecomposer extends AlgorithmDecomposer { |
|
38 |
|
39 // indicates that only certification path algorithms need to be used |
|
40 private final boolean onlyX509; |
|
41 |
|
42 SSLAlgorithmDecomposer(boolean onlyX509) { |
|
43 this.onlyX509 = onlyX509; |
|
44 } |
|
45 |
|
46 SSLAlgorithmDecomposer() { |
|
47 this(false); |
|
48 } |
|
49 |
|
50 private Set<String> decomposes(CipherSuite.KeyExchange keyExchange) { |
|
51 Set<String> components = new HashSet<>(); |
|
52 switch (keyExchange) { |
|
53 case K_NULL: |
|
54 if (!onlyX509) { |
|
55 components.add("K_NULL"); |
|
56 } |
|
57 break; |
|
58 case K_RSA: |
|
59 components.add("RSA"); |
|
60 break; |
|
61 case K_RSA_EXPORT: |
|
62 components.add("RSA"); |
|
63 components.add("RSA_EXPORT"); |
|
64 break; |
|
65 case K_DH_RSA: |
|
66 components.add("RSA"); |
|
67 components.add("DH"); |
|
68 components.add("DiffieHellman"); |
|
69 components.add("DH_RSA"); |
|
70 break; |
|
71 case K_DH_DSS: |
|
72 components.add("DSA"); |
|
73 components.add("DSS"); |
|
74 components.add("DH"); |
|
75 components.add("DiffieHellman"); |
|
76 components.add("DH_DSS"); |
|
77 break; |
|
78 case K_DHE_DSS: |
|
79 components.add("DSA"); |
|
80 components.add("DSS"); |
|
81 components.add("DH"); |
|
82 components.add("DHE"); |
|
83 components.add("DiffieHellman"); |
|
84 components.add("DHE_DSS"); |
|
85 break; |
|
86 case K_DHE_RSA: |
|
87 components.add("RSA"); |
|
88 components.add("DH"); |
|
89 components.add("DHE"); |
|
90 components.add("DiffieHellman"); |
|
91 components.add("DHE_RSA"); |
|
92 break; |
|
93 case K_DH_ANON: |
|
94 if (!onlyX509) { |
|
95 components.add("ANON"); |
|
96 components.add("DH"); |
|
97 components.add("DiffieHellman"); |
|
98 components.add("DH_ANON"); |
|
99 } |
|
100 break; |
|
101 case K_ECDH_ECDSA: |
|
102 components.add("ECDH"); |
|
103 components.add("ECDSA"); |
|
104 components.add("ECDH_ECDSA"); |
|
105 break; |
|
106 case K_ECDH_RSA: |
|
107 components.add("ECDH"); |
|
108 components.add("RSA"); |
|
109 components.add("ECDH_RSA"); |
|
110 break; |
|
111 case K_ECDHE_ECDSA: |
|
112 components.add("ECDHE"); |
|
113 components.add("ECDSA"); |
|
114 components.add("ECDHE_ECDSA"); |
|
115 break; |
|
116 case K_ECDHE_RSA: |
|
117 components.add("ECDHE"); |
|
118 components.add("RSA"); |
|
119 components.add("ECDHE_RSA"); |
|
120 break; |
|
121 case K_ECDH_ANON: |
|
122 if (!onlyX509) { |
|
123 components.add("ECDH"); |
|
124 components.add("ANON"); |
|
125 components.add("ECDH_ANON"); |
|
126 } |
|
127 break; |
|
128 default: |
|
129 if (ClientKeyExchangeService.find(keyExchange.name) != null) { |
|
130 if (!onlyX509) { |
|
131 components.add(keyExchange.name); |
|
132 } |
|
133 } |
|
134 // otherwise ignore |
|
135 } |
|
136 |
|
137 return components; |
|
138 } |
|
139 |
|
140 private Set<String> decomposes(CipherSuite.BulkCipher bulkCipher) { |
|
141 Set<String> components = new HashSet<>(); |
|
142 |
|
143 if (bulkCipher.transformation != null) { |
|
144 components.addAll(super.decompose(bulkCipher.transformation)); |
|
145 } |
|
146 |
|
147 switch (bulkCipher) { |
|
148 case B_NULL: |
|
149 components.add("C_NULL"); |
|
150 break; |
|
151 case B_RC2_40: |
|
152 components.add("RC2_CBC_40"); |
|
153 break; |
|
154 case B_RC4_40: |
|
155 components.add("RC4_40"); |
|
156 break; |
|
157 case B_RC4_128: |
|
158 components.add("RC4_128"); |
|
159 break; |
|
160 case B_DES_40: |
|
161 components.add("DES40_CBC"); |
|
162 components.add("DES_CBC_40"); |
|
163 break; |
|
164 case B_DES: |
|
165 components.add("DES_CBC"); |
|
166 break; |
|
167 case B_3DES: |
|
168 components.add("3DES_EDE_CBC"); |
|
169 break; |
|
170 case B_AES_128: |
|
171 components.add("AES_128_CBC"); |
|
172 break; |
|
173 case B_AES_256: |
|
174 components.add("AES_256_CBC"); |
|
175 break; |
|
176 case B_AES_128_GCM: |
|
177 components.add("AES_128_GCM"); |
|
178 break; |
|
179 case B_AES_256_GCM: |
|
180 components.add("AES_256_GCM"); |
|
181 break; |
|
182 } |
|
183 |
|
184 return components; |
|
185 } |
|
186 |
|
187 private Set<String> decomposes(CipherSuite.MacAlg macAlg, |
|
188 BulkCipher cipher) { |
|
189 Set<String> components = new HashSet<>(); |
|
190 |
|
191 if (macAlg == CipherSuite.MacAlg.M_NULL |
|
192 && cipher.cipherType != CipherType.AEAD_CIPHER) { |
|
193 components.add("M_NULL"); |
|
194 } else if (macAlg == CipherSuite.MacAlg.M_MD5) { |
|
195 components.add("MD5"); |
|
196 components.add("HmacMD5"); |
|
197 } else if (macAlg == CipherSuite.MacAlg.M_SHA) { |
|
198 components.add("SHA1"); |
|
199 components.add("SHA-1"); |
|
200 components.add("HmacSHA1"); |
|
201 } else if (macAlg == CipherSuite.MacAlg.M_SHA256) { |
|
202 components.add("SHA256"); |
|
203 components.add("SHA-256"); |
|
204 components.add("HmacSHA256"); |
|
205 } else if (macAlg == CipherSuite.MacAlg.M_SHA384) { |
|
206 components.add("SHA384"); |
|
207 components.add("SHA-384"); |
|
208 components.add("HmacSHA384"); |
|
209 } |
|
210 |
|
211 return components; |
|
212 } |
|
213 |
|
214 private Set<String> decompose(KeyExchange keyExchange, BulkCipher cipher, |
|
215 MacAlg macAlg) { |
|
216 Set<String> components = new HashSet<>(); |
|
217 |
|
218 if (keyExchange != null) { |
|
219 components.addAll(decomposes(keyExchange)); |
|
220 } |
|
221 |
|
222 if (onlyX509) { |
|
223 // Certification path algorithm constraints do not apply |
|
224 // to cipher and macAlg. |
|
225 return components; |
|
226 } |
|
227 |
|
228 if (cipher != null) { |
|
229 components.addAll(decomposes(cipher)); |
|
230 } |
|
231 |
|
232 if (macAlg != null) { |
|
233 components.addAll(decomposes(macAlg, cipher)); |
|
234 } |
|
235 |
|
236 return components; |
|
237 } |
|
238 |
|
239 @Override |
|
240 public Set<String> decompose(String algorithm) { |
|
241 if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) { |
|
242 CipherSuite cipherSuite = null; |
|
243 try { |
|
244 cipherSuite = CipherSuite.valueOf(algorithm); |
|
245 } catch (IllegalArgumentException iae) { |
|
246 // ignore: unknown or unsupported ciphersuite |
|
247 } |
|
248 |
|
249 if (cipherSuite != null) { |
|
250 return decompose(cipherSuite.keyExchange, cipherSuite.cipher, |
|
251 cipherSuite.macAlg); |
|
252 } |
|
253 } |
|
254 |
|
255 return super.decompose(algorithm); |
|
256 } |
|
257 |
|
258 } |