101 |
99 |
102 } |
100 } |
103 |
101 |
104 public static class TestParameters { |
102 public static class TestParameters { |
105 |
103 |
106 String cipherSuite; |
104 CipherSuite cipherSuite; |
107 String protocol; |
105 Protocol protocol; |
108 String clientAuth; |
106 String clientAuth; |
109 |
107 |
110 TestParameters(String cipherSuite, String protocol, |
108 TestParameters(CipherSuite cipherSuite, Protocol protocol, |
111 String clientAuth) { |
109 String clientAuth) { |
112 this.cipherSuite = cipherSuite; |
110 this.cipherSuite = cipherSuite; |
113 this.protocol = protocol; |
111 this.protocol = protocol; |
114 this.clientAuth = clientAuth; |
112 this.clientAuth = clientAuth; |
115 } |
113 } |
116 |
114 |
117 boolean isEnabled() { |
115 boolean isEnabled() { |
118 return TLSCipherStatus.isEnabled(cipherSuite, protocol); |
116 return cipherSuite.supportedByProtocol(protocol); |
119 } |
117 } |
120 |
118 |
121 public String toString() { |
119 public String toString() { |
122 String s = cipherSuite + " in " + protocol + " mode"; |
120 String s = cipherSuite + " in " + protocol + " mode"; |
123 if (clientAuth != null) { |
121 if (clientAuth != null) { |
124 s += " with " + clientAuth + " client authentication"; |
122 s += " with " + clientAuth + " client authentication"; |
125 } |
123 } |
126 return s; |
124 return s; |
127 } |
|
128 |
|
129 static enum TLSCipherStatus { |
|
130 // cipher suites supported since TLS 1.2 |
|
131 CS_01("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", 0x0303, 0xFFFF), |
|
132 CS_02("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", 0x0303, 0xFFFF), |
|
133 CS_03("TLS_RSA_WITH_AES_256_CBC_SHA256", 0x0303, 0xFFFF), |
|
134 CS_04("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", 0x0303, 0xFFFF), |
|
135 CS_05("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", 0x0303, 0xFFFF), |
|
136 CS_06("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", 0x0303, 0xFFFF), |
|
137 CS_07("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", 0x0303, 0xFFFF), |
|
138 |
|
139 CS_08("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 0x0303, 0xFFFF), |
|
140 CS_09("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", 0x0303, 0xFFFF), |
|
141 CS_10("TLS_RSA_WITH_AES_128_CBC_SHA256", 0x0303, 0xFFFF), |
|
142 CS_11("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", 0x0303, 0xFFFF), |
|
143 CS_12("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", 0x0303, 0xFFFF), |
|
144 CS_13("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", 0x0303, 0xFFFF), |
|
145 CS_14("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", 0x0303, 0xFFFF), |
|
146 |
|
147 CS_15("TLS_DH_anon_WITH_AES_256_CBC_SHA256", 0x0303, 0xFFFF), |
|
148 CS_16("TLS_DH_anon_WITH_AES_128_CBC_SHA256", 0x0303, 0xFFFF), |
|
149 CS_17("TLS_RSA_WITH_NULL_SHA256", 0x0303, 0xFFFF), |
|
150 |
|
151 CS_20("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 0x0303, 0xFFFF), |
|
152 CS_21("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 0x0303, 0xFFFF), |
|
153 CS_22("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", 0x0303, 0xFFFF), |
|
154 CS_23("TLS_RSA_WITH_AES_256_GCM_SHA384", 0x0303, 0xFFFF), |
|
155 CS_24("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", 0x0303, 0xFFFF), |
|
156 CS_25("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", 0x0303, 0xFFFF), |
|
157 CS_26("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", 0x0303, 0xFFFF), |
|
158 CS_27("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", 0x0303, 0xFFFF), |
|
159 |
|
160 CS_28("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 0x0303, 0xFFFF), |
|
161 CS_29("TLS_RSA_WITH_AES_128_GCM_SHA256", 0x0303, 0xFFFF), |
|
162 CS_30("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", 0x0303, 0xFFFF), |
|
163 CS_31("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", 0x0303, 0xFFFF), |
|
164 CS_32("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", 0x0303, 0xFFFF), |
|
165 CS_33("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", 0x0303, 0xFFFF), |
|
166 |
|
167 CS_34("TLS_DH_anon_WITH_AES_256_GCM_SHA384", 0x0303, 0xFFFF), |
|
168 CS_35("TLS_DH_anon_WITH_AES_128_GCM_SHA256", 0x0303, 0xFFFF), |
|
169 |
|
170 // cipher suites obsoleted since TLS 1.2 |
|
171 CS_50("SSL_RSA_WITH_DES_CBC_SHA", 0x0000, 0x0303), |
|
172 CS_51("SSL_DHE_RSA_WITH_DES_CBC_SHA", 0x0000, 0x0303), |
|
173 CS_52("SSL_DHE_DSS_WITH_DES_CBC_SHA", 0x0000, 0x0303), |
|
174 CS_53("SSL_DH_anon_WITH_DES_CBC_SHA", 0x0000, 0x0303), |
|
175 CS_54("TLS_KRB5_WITH_DES_CBC_SHA", 0x0000, 0x0303), |
|
176 CS_55("TLS_KRB5_WITH_DES_CBC_MD5", 0x0000, 0x0303), |
|
177 |
|
178 // cipher suites obsoleted since TLS 1.1 |
|
179 CS_60("SSL_RSA_EXPORT_WITH_RC4_40_MD5", 0x0000, 0x0302), |
|
180 CS_61("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", 0x0000, 0x0302), |
|
181 CS_62("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x0000, 0x0302), |
|
182 CS_63("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x0000, 0x0302), |
|
183 CS_64("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", 0x0000, 0x0302), |
|
184 CS_65("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", 0x0000, 0x0302), |
|
185 CS_66("TLS_KRB5_EXPORT_WITH_RC4_40_SHA", 0x0000, 0x0302), |
|
186 CS_67("TLS_KRB5_EXPORT_WITH_RC4_40_MD5", 0x0000, 0x0302), |
|
187 CS_68("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", 0x0000, 0x0302), |
|
188 CS_69("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", 0x0000, 0x0302), |
|
189 |
|
190 // ignore TLS_EMPTY_RENEGOTIATION_INFO_SCSV always |
|
191 CS_99("TLS_EMPTY_RENEGOTIATION_INFO_SCSV", 0xFFFF, 0x0000); |
|
192 |
|
193 // the cipher suite name |
|
194 final String cipherSuite; |
|
195 |
|
196 // supported since protocol version |
|
197 final int supportedSince; |
|
198 |
|
199 // obsoleted since protocol version |
|
200 final int obsoletedSince; |
|
201 |
|
202 TLSCipherStatus(String cipherSuite, |
|
203 int supportedSince, int obsoletedSince) { |
|
204 this.cipherSuite = cipherSuite; |
|
205 this.supportedSince = supportedSince; |
|
206 this.obsoletedSince = obsoletedSince; |
|
207 } |
|
208 |
|
209 static boolean isEnabled(String cipherSuite, String protocol) { |
|
210 int versionNumber = toVersionNumber(protocol); |
|
211 |
|
212 if (versionNumber < 0) { |
|
213 return true; // unlikely to happen |
|
214 } |
|
215 |
|
216 for (TLSCipherStatus status : TLSCipherStatus.values()) { |
|
217 if (cipherSuite.equals(status.cipherSuite)) { |
|
218 if ((versionNumber < status.supportedSince) || |
|
219 (versionNumber >= status.obsoletedSince)) { |
|
220 return false; |
|
221 } |
|
222 |
|
223 return true; |
|
224 } |
|
225 } |
|
226 |
|
227 return true; |
|
228 } |
|
229 |
|
230 private static int toVersionNumber(String protocol) { |
|
231 int versionNumber = -1; |
|
232 |
|
233 switch (protocol) { |
|
234 case "SSLv2Hello": |
|
235 versionNumber = 0x0002; |
|
236 break; |
|
237 case "SSLv3": |
|
238 versionNumber = 0x0300; |
|
239 break; |
|
240 case "TLSv1": |
|
241 versionNumber = 0x0301; |
|
242 break; |
|
243 case "TLSv1.1": |
|
244 versionNumber = 0x0302; |
|
245 break; |
|
246 case "TLSv1.2": |
|
247 versionNumber = 0x0303; |
|
248 break; |
|
249 default: |
|
250 // unlikely to happen |
|
251 } |
|
252 |
|
253 return versionNumber; |
|
254 } |
|
255 } |
125 } |
256 } |
126 } |
257 |
127 |
258 private List<TestParameters> tests; |
128 private List<TestParameters> tests; |
259 private Iterator<TestParameters> testIterator; |
129 private Iterator<TestParameters> testIterator; |
267 String[] cipherSuites = socket.getSupportedCipherSuites(); |
137 String[] cipherSuites = socket.getSupportedCipherSuites(); |
268 String[] protocols = socket.getSupportedProtocols(); |
138 String[] protocols = socket.getSupportedProtocols(); |
269 String[] clientAuths = {null, "RSA", "DSA"}; |
139 String[] clientAuths = {null, "RSA", "DSA"}; |
270 tests = new ArrayList<TestParameters>( |
140 tests = new ArrayList<TestParameters>( |
271 cipherSuites.length * protocols.length * clientAuths.length); |
141 cipherSuites.length * protocols.length * clientAuths.length); |
272 for (int i = 0; i < cipherSuites.length; i++) { |
142 for (int j = 0; j < protocols.length; j++) { |
273 String cipherSuite = cipherSuites[i]; |
143 String protocol = protocols[j]; |
274 |
144 if (protocol.equals(Protocol.SSLV2HELLO.name)) { |
275 for (int j = 0; j < protocols.length; j++) { |
145 System.out.println("Skipping SSLv2Hello protocol"); |
276 String protocol = protocols[j]; |
146 continue; |
|
147 } |
|
148 |
|
149 for (int i = 0; i < cipherSuites.length; i++) { |
|
150 String cipherSuite = cipherSuites[i]; |
|
151 |
|
152 // skip kerberos cipher suites and TLS_EMPTY_RENEGOTIATION_INFO_SCSV |
|
153 if (cipherSuite.startsWith("TLS_KRB5") || cipherSuite.equals( |
|
154 CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV.name())) { |
|
155 System.out.println("Skipping unsupported test for " + |
|
156 cipherSuite + " of " + protocol); |
|
157 continue; |
|
158 } |
277 |
159 |
278 if (!peerFactory.isSupported(cipherSuite, protocol)) { |
160 if (!peerFactory.isSupported(cipherSuite, protocol)) { |
279 continue; |
161 continue; |
280 } |
162 } |
281 |
163 |
282 for (int k = 0; k < clientAuths.length; k++) { |
164 for (int k = 0; k < clientAuths.length; k++) { |
283 String clientAuth = clientAuths[k]; |
165 String clientAuth = clientAuths[k]; |
284 if ((clientAuth != null) && |
166 // no client with anonymous cipher suites; |
285 (cipherSuite.indexOf("DH_anon") != -1)) { |
167 // TLS 1.3 doesn't support DSA |
286 // no client with anonymous ciphersuites |
168 if ((clientAuth != null && cipherSuite.contains("DH_anon")) |
|
169 || ("DSA".equals(clientAuth) && "TLSv1.3".equals(protocol))) { |
287 continue; |
170 continue; |
288 } |
171 } |
289 tests.add(new TestParameters(cipherSuite, protocol, |
172 tests.add(new TestParameters( |
290 clientAuth)); |
173 CipherSuite.cipherSuite(cipherSuite), |
|
174 Protocol.protocol(protocol), |
|
175 clientAuth)); |
291 } |
176 } |
292 } |
177 } |
293 } |
178 } |
294 testIterator = tests.iterator(); |
179 testIterator = tests.iterator(); |
295 } |
180 } |