001 /*
002 * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.11/src/java/org/apache/commons/ssl/SSL.java $
003 * $Revision: 155 $
004 * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $
005 *
006 * ====================================================================
007 * Licensed to the Apache Software Foundation (ASF) under one
008 * or more contributor license agreements. See the NOTICE file
009 * distributed with this work for additional information
010 * regarding copyright ownership. The ASF licenses this file
011 * to you under the Apache License, Version 2.0 (the
012 * "License"); you may not use this file except in compliance
013 * with the License. You may obtain a copy of the License at
014 *
015 * http://www.apache.org/licenses/LICENSE-2.0
016 *
017 * Unless required by applicable law or agreed to in writing,
018 * software distributed under the License is distributed on an
019 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
020 * KIND, either express or implied. See the License for the
021 * specific language governing permissions and limitations
022 * under the License.
023 * ====================================================================
024 *
025 * This software consists of voluntary contributions made by many
026 * individuals on behalf of the Apache Software Foundation. For more
027 * information on the Apache Software Foundation, please see
028 * <http://www.apache.org/>.
029 *
030 */
031
032 package org.apache.commons.ssl;
033
034 import javax.net.SocketFactory;
035 import javax.net.ssl.*;
036 import java.io.File;
037 import java.io.IOException;
038 import java.net.InetAddress;
039 import java.net.ServerSocket;
040 import java.net.Socket;
041 import java.net.UnknownHostException;
042 import java.security.GeneralSecurityException;
043 import java.security.KeyManagementException;
044 import java.security.KeyStoreException;
045 import java.security.NoSuchAlgorithmException;
046 import java.security.cert.CertificateException;
047 import java.security.cert.X509Certificate;
048 import java.util.*;
049
050 /**
051 * Not thread-safe. (But who would ever share this thing across multiple
052 * threads???)
053 *
054 * @author Credit Union Central of British Columbia
055 * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
056 * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
057 * @since May 1, 2006
058 */
059 public class SSL {
060 private final static String[] KNOWN_PROTOCOLS =
061 {"TLSv1", "SSLv3", "SSLv2", "SSLv2Hello"};
062
063 // SUPPORTED_CIPHERS_ARRAY is initialized in the static constructor.
064 private final static String[] SUPPORTED_CIPHERS;
065
066 public final static SortedSet KNOWN_PROTOCOLS_SET;
067 public final static SortedSet SUPPORTED_CIPHERS_SET;
068
069 // RC4
070 public final static String SSL_RSA_WITH_RC4_128_SHA = "SSL_RSA_WITH_RC4_128_SHA";
071
072 // 3DES
073 public final static String SSL_RSA_WITH_3DES_EDE_CBC_SHA = "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
074 public final static String SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
075 public final static String SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA = "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
076
077 // AES-128
078 public final static String TLS_RSA_WITH_AES_128_CBC_SHA = "TLS_RSA_WITH_AES_128_CBC_SHA";
079 public final static String TLS_DHE_RSA_WITH_AES_128_CBC_SHA = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
080 public final static String TLS_DHE_DSS_WITH_AES_128_CBC_SHA = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
081
082 // AES-256
083 public final static String TLS_RSA_WITH_AES_256_CBC_SHA = "TLS_RSA_WITH_AES_256_CBC_SHA";
084 public final static String TLS_DHE_RSA_WITH_AES_256_CBC_SHA = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
085 public final static String TLS_DHE_DSS_WITH_AES_256_CBC_SHA = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
086
087 static {
088 TreeSet ts = new TreeSet(Collections.reverseOrder());
089 ts.addAll(Arrays.asList(KNOWN_PROTOCOLS));
090 KNOWN_PROTOCOLS_SET = Collections.unmodifiableSortedSet(ts);
091
092 // SSLSocketFactory.getDefault() sometimes blocks on FileInputStream
093 // reads of "/dev/random" (Linux only?). You might find you system
094 // stuck here. Move the mouse around a little!
095 SSLSocketFactory s = (SSLSocketFactory) SSLSocketFactory.getDefault();
096 ts = new TreeSet();
097 SUPPORTED_CIPHERS = s.getSupportedCipherSuites();
098 Arrays.sort(SUPPORTED_CIPHERS);
099 ts.addAll(Arrays.asList(SUPPORTED_CIPHERS));
100 SUPPORTED_CIPHERS_SET = Collections.unmodifiableSortedSet(ts);
101 }
102
103 private Object sslContext = null;
104 private int initCount = 0;
105 private SSLSocketFactory socketFactory = null;
106 private SSLServerSocketFactory serverSocketFactory = null;
107 private HostnameVerifier hostnameVerifier = HostnameVerifier.DEFAULT;
108 private boolean isSecure = true; // if false, the client-style operations only create plain sockets.
109 private boolean checkHostname = true;
110 private boolean checkCRL = true;
111 private boolean checkExpiry = true;
112 private boolean useClientMode = false;
113 private boolean useClientModeDefault = true;
114 private int soTimeout = 24 * 60 * 60 * 1000; // default: one day
115 private int connectTimeout = 60 * 60 * 1000; // default: one hour
116 private TrustChain trustChain = null;
117 private KeyMaterial keyMaterial = null;
118 private String[] enabledCiphers = null;
119 private String[] enabledProtocols = null;
120 private String defaultProtocol = "TLS";
121 private X509Certificate[] currentServerChain;
122 private X509Certificate[] currentClientChain;
123 private boolean wantClientAuth = true;
124 private boolean needClientAuth = false;
125 private SSLWrapperFactory sslWrapperFactory = SSLWrapperFactory.NO_WRAP;
126 private Map dnsOverride;
127
128 protected final boolean usingSystemProperties;
129
130 public SSL()
131 throws GeneralSecurityException, IOException {
132 boolean usingSysProps = false;
133 Properties props = System.getProperties();
134 boolean ksSet = props.containsKey("javax.net.ssl.keyStore");
135 boolean tsSet = props.containsKey("javax.net.ssl.trustStore");
136 if (ksSet) {
137 String path = System.getProperty("javax.net.ssl.keyStore");
138 String pwd = System.getProperty("javax.net.ssl.keyStorePassword");
139 pwd = pwd != null ? pwd : ""; // JSSE default is "".
140 File f = new File(path);
141 if (f.exists()) {
142 KeyMaterial km = new KeyMaterial(path, pwd.toCharArray());
143 setKeyMaterial(km);
144 usingSysProps = true;
145 }
146 }
147 boolean trustMaterialSet = false;
148 if (tsSet) {
149 String path = System.getProperty("javax.net.ssl.trustStore");
150 String pwd = System.getProperty("javax.net.ssl.trustStorePassword");
151 boolean pwdWasNull = pwd == null;
152 pwd = pwdWasNull ? "" : pwd; // JSSE default is "".
153 File f = new File(path);
154 if (f.exists()) {
155 TrustMaterial tm;
156 try {
157 tm = new TrustMaterial(path, pwd.toCharArray());
158 }
159 catch (GeneralSecurityException gse) {
160 // Probably a bad password. If we're using the default password,
161 // let's try and survive this setback.
162 if (pwdWasNull) {
163 tm = new TrustMaterial(path);
164 } else {
165 throw gse;
166 }
167 }
168
169 setTrustMaterial(tm);
170 usingSysProps = true;
171 trustMaterialSet = true;
172 }
173 }
174
175 /*
176 No default trust material was set. We'll use the JSSE standard way
177 where we test for "JSSE_CACERTS" first, and then fall back on
178 "CACERTS". We could just leave TrustMaterial null, but then our
179 setCheckCRL() and setCheckExpiry() features won't work. We need a
180 non-null TrustMaterial object in order to intercept and decorate
181 the JVM's default TrustManager.
182 */
183 if (!trustMaterialSet) {
184 setTrustMaterial(TrustMaterial.DEFAULT);
185 }
186 this.usingSystemProperties = usingSysProps;
187
188 // By default we only use the strong ciphers (128 bit and higher).
189 // Consumers can call "useDefaultJavaCiphers()" to get the 40 and 56 bit
190 // ciphers back that Java normally has turned on.
191 useStrongCiphers();
192 dirtyAndReloadIfYoung();
193 }
194
195 private void dirty() {
196 this.sslContext = null;
197 this.socketFactory = null;
198 this.serverSocketFactory = null;
199 }
200
201 private void dirtyAndReloadIfYoung()
202 throws NoSuchAlgorithmException, KeyStoreException,
203 KeyManagementException, IOException, CertificateException {
204 dirty();
205 if (initCount >= 0 && initCount <= 5) {
206 // The first five init's we do early (before any sockets are
207 // created) in the hope that will trigger any explosions nice
208 // and early, with the correct exception type.
209
210 // After the first five init's, we revert to a regular
211 // dirty / init pattern, and the "init" happens very late:
212 // just before the socket is created. If badness happens, a
213 // wrapping RuntimeException will be thrown.
214 init();
215 }
216 }
217
218 String dnsOverride(String host) {
219 if (dnsOverride != null && dnsOverride.containsKey(host)) {
220 String override = (String) dnsOverride.get(host);
221 if (override != null && !"".equals(override.trim())) {
222 return override;
223 }
224 }
225 return host;
226 }
227
228 public void setDnsOverride(Map m) {
229 this.dnsOverride = m;
230 }
231
232 public void setIsSecure(boolean b) {
233 this.isSecure = b;
234 }
235
236 public boolean isSecure() {
237 return isSecure;
238 }
239
240 public SSLContext getSSLContext()
241 throws GeneralSecurityException, IOException
242
243 {
244 Object obj = getSSLContextAsObject();
245 if (JavaImpl.isJava13()) {
246 try {
247 return (SSLContext) obj;
248 }
249 catch (ClassCastException cce) {
250 throw new ClassCastException("When using Java13 SSL, you must call SSL.getSSLContextAsObject() - " + cce);
251 }
252 }
253 return (SSLContext) obj;
254 }
255
256 /**
257 * @return com.sun.net.ssl.SSLContext or javax.net.ssl.SSLContext depending
258 * on the JSSE implementation we're using.
259 * @throws GeneralSecurityException problem creating SSLContext
260 * @throws IOException problem creating SSLContext
261 */
262 public Object getSSLContextAsObject()
263 throws GeneralSecurityException, IOException
264
265 {
266 if (sslContext == null) {
267 init();
268 }
269 return sslContext;
270 }
271
272 public void addTrustMaterial(TrustChain trustChain)
273 throws NoSuchAlgorithmException, KeyStoreException,
274 KeyManagementException, IOException, CertificateException {
275 if (this.trustChain == null || trustChain == TrustMaterial.TRUST_ALL) {
276 this.trustChain = trustChain;
277 } else {
278 this.trustChain.addTrustMaterial(trustChain);
279 }
280 dirtyAndReloadIfYoung();
281 }
282
283 public void setTrustMaterial(TrustChain trustChain)
284 throws NoSuchAlgorithmException, KeyStoreException,
285 KeyManagementException, IOException, CertificateException {
286 this.trustChain = trustChain;
287 dirtyAndReloadIfYoung();
288 }
289
290 public void setKeyMaterial(KeyMaterial keyMaterial)
291 throws NoSuchAlgorithmException, KeyStoreException,
292 KeyManagementException, IOException, CertificateException {
293 this.keyMaterial = keyMaterial;
294 dirtyAndReloadIfYoung();
295 }
296
297 public X509Certificate[] getAssociatedCertificateChain() {
298 if (keyMaterial != null) {
299 List list = keyMaterial.getAssociatedCertificateChains();
300 return (X509Certificate[]) list.get(0);
301 } else {
302 return null;
303 }
304 }
305
306 public String[] getEnabledCiphers() {
307 return enabledCiphers != null ? enabledCiphers : getDefaultCipherSuites();
308 }
309
310 public void useDefaultJavaCiphers() {
311 this.enabledCiphers = null;
312 }
313
314 public void useStrongCiphers() {
315 LinkedList list = new LinkedList();
316 addCipher(list, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, false);
317 addCipher(list, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, false);
318 addCipher(list, SSL_RSA_WITH_3DES_EDE_CBC_SHA, false);
319 addCipher(list, SSL_RSA_WITH_RC4_128_SHA, false);
320 addCipher(list, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, false);
321 addCipher(list, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, false);
322 addCipher(list, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, false);
323 addCipher(list, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, false);
324 addCipher(list, TLS_RSA_WITH_AES_128_CBC_SHA, false);
325 addCipher(list, TLS_RSA_WITH_AES_256_CBC_SHA, false);
326 String[] strongCiphers = new String[list.size()];
327 list.toArray(strongCiphers);
328 String[] currentCiphers = getEnabledCiphers();
329 // Current ciphers must be default or something. Odd that it's null,
330 // though.
331 if (currentCiphers == null) {
332 setEnabledCiphers(strongCiphers);
333 }
334
335 Arrays.sort(strongCiphers);
336 Arrays.sort(currentCiphers);
337 // Let's only call "setEnabledCiphers" if our array is actually different
338 // than what's already set.
339 if (!Arrays.equals(strongCiphers, currentCiphers)) {
340 setEnabledCiphers(strongCiphers);
341 }
342 }
343
344 public void setEnabledCiphers(String[] ciphers) {
345 HashSet desired = new HashSet(Arrays.asList(ciphers));
346 desired.removeAll(SUPPORTED_CIPHERS_SET);
347 if (!desired.isEmpty()) {
348 throw new IllegalArgumentException("following ciphers not supported: " + desired);
349 }
350 this.enabledCiphers = ciphers;
351 }
352
353 public String[] getEnabledProtocols() {
354 return enabledProtocols != null ? enabledProtocols : KNOWN_PROTOCOLS;
355 }
356
357 public void setEnabledProtocols(String[] protocols) {
358 HashSet desired = new HashSet(Arrays.asList(protocols));
359 desired.removeAll(KNOWN_PROTOCOLS_SET);
360 if (!desired.isEmpty()) {
361 throw new IllegalArgumentException("following protocols not supported: " + desired);
362 }
363 this.enabledProtocols = protocols;
364 }
365
366 public String getDefaultProtocol() {
367 return defaultProtocol;
368 }
369
370 public void setDefaultProtocol(String protocol) {
371 this.defaultProtocol = protocol;
372 dirty();
373 }
374
375 public boolean getCheckHostname() {
376 return checkHostname;
377 }
378
379 public void setCheckHostname(boolean checkHostname) {
380 this.checkHostname = checkHostname;
381 }
382
383 public void setHostnameVerifier(HostnameVerifier verifier) {
384 if (verifier == null) {
385 verifier = HostnameVerifier.DEFAULT;
386 }
387 this.hostnameVerifier = verifier;
388 }
389
390 public HostnameVerifier getHostnameVerifier() {
391 return hostnameVerifier;
392 }
393
394 public boolean getCheckCRL() {
395 return checkCRL;
396 }
397
398 public void setCheckCRL(boolean checkCRL) {
399 this.checkCRL = checkCRL;
400 }
401
402 public boolean getCheckExpiry() {
403 return checkExpiry;
404 }
405
406 public void setCheckExpiry(boolean checkExpiry) {
407 this.checkExpiry = checkExpiry;
408 }
409
410 public void setSoTimeout(int soTimeout) {
411 if (soTimeout < 0) {
412 throw new IllegalArgumentException("soTimeout must not be negative");
413 }
414 this.soTimeout = soTimeout;
415 }
416
417 public int getSoTimeout() {
418 return soTimeout;
419 }
420
421 public void setConnectTimeout(int connectTimeout) {
422 if (connectTimeout < 0) {
423 throw new IllegalArgumentException("connectTimeout must not be negative");
424 }
425 this.connectTimeout = connectTimeout;
426 }
427
428 public void setUseClientMode(boolean useClientMode) {
429 this.useClientModeDefault = false;
430 this.useClientMode = useClientMode;
431 }
432
433 public boolean getUseClientModeDefault() {
434 return useClientModeDefault;
435 }
436
437 public boolean getUseClientMode() {
438 return useClientMode;
439 }
440
441 public void setWantClientAuth(boolean wantClientAuth) {
442 this.wantClientAuth = wantClientAuth;
443 }
444
445 public void setNeedClientAuth(boolean needClientAuth) {
446 this.needClientAuth = needClientAuth;
447 }
448
449 public boolean getWantClientAuth() {
450 return wantClientAuth;
451 }
452
453 public boolean getNeedClientAuth() {
454 return needClientAuth;
455 }
456
457 public SSLWrapperFactory getSSLWrapperFactory() {
458 return this.sslWrapperFactory;
459 }
460
461 public void setSSLWrapperFactory(SSLWrapperFactory wf) {
462 this.sslWrapperFactory = wf;
463 }
464
465 private void initThrowRuntime() {
466 try {
467 init();
468 }
469 catch (GeneralSecurityException gse) {
470 throw JavaImpl.newRuntimeException(gse);
471 }
472 catch (IOException ioe) {
473 throw JavaImpl.newRuntimeException(ioe);
474 }
475 }
476
477 private void init()
478 throws NoSuchAlgorithmException, KeyStoreException,
479 KeyManagementException, IOException, CertificateException {
480 socketFactory = null;
481 serverSocketFactory = null;
482 this.sslContext = JavaImpl.init(this, trustChain, keyMaterial);
483 initCount++;
484 }
485
486 public void doPreConnectSocketStuff(Socket s) throws IOException {
487 if (s instanceof SSLSocket && !useClientModeDefault) {
488 ((SSLSocket) s).setUseClientMode(useClientMode);
489 }
490 if (soTimeout > 0) {
491 s.setSoTimeout(soTimeout);
492 }
493 if (s instanceof SSLSocket) {
494 if (enabledProtocols != null) {
495 JavaImpl.setEnabledProtocols(s, enabledProtocols);
496 }
497 if (enabledCiphers != null) {
498 ((SSLSocket) s).setEnabledCipherSuites(enabledCiphers);
499 }
500 }
501 }
502
503 public void doPostConnectSocketStuff(Socket s, String host)
504 throws IOException {
505 if (checkHostname && s instanceof SSLSocket) {
506 hostnameVerifier.check(host, (SSLSocket) s);
507 }
508 }
509
510 public Socket createSocket() throws IOException {
511 if (isSecure) {
512 return sslWrapperFactory.wrap(JavaImpl.createSocket(this));
513 } else {
514 Socket s = SocketFactory.getDefault().createSocket();
515 doPreConnectSocketStuff(s);
516 return s;
517 }
518 }
519
520 /**
521 * Attempts to get a new socket connection to the given host within the
522 * given time limit.
523 *
524 * @param remoteHost the host name/IP
525 * @param remotePort the port on the host
526 * @param localHost the local host name/IP to bind the socket to
527 * @param localPort the port on the local machine
528 * @param timeout the connection timeout (0==infinite)
529 * @return Socket a new socket
530 * @throws IOException if an I/O error occurs while creating the socket
531 * @throws UnknownHostException if the IP address of the host cannot be
532 * determined
533 */
534 public Socket createSocket(
535 String remoteHost, int remotePort, InetAddress localHost, int localPort, int timeout
536 ) throws IOException {
537 // Only use our factory-wide connectTimeout if this method was passed
538 // in a timeout of 0 (infinite).
539 int factoryTimeout = getConnectTimeout();
540 int connectTimeout = timeout == 0 ? factoryTimeout : timeout;
541 Socket s;
542 if (isSecure) {
543 s = JavaImpl.createSocket(
544 this, remoteHost, remotePort, localHost, localPort, connectTimeout
545 );
546 } else {
547 s = JavaImpl.createPlainSocket(
548 this, remoteHost, remotePort, localHost, localPort, connectTimeout
549 );
550 }
551 return sslWrapperFactory.wrap(s);
552 }
553
554 public Socket createSocket(
555 Socket s, String remoteHost, int remotePort, boolean autoClose
556 ) throws IOException {
557 SSLSocketFactory sf = getSSLSocketFactory();
558 s = sf.createSocket(s, remoteHost, remotePort, autoClose);
559 doPreConnectSocketStuff(s);
560 doPostConnectSocketStuff(s, remoteHost);
561 return sslWrapperFactory.wrap(s);
562 }
563
564 public ServerSocket createServerSocket() throws IOException {
565 SSLServerSocket ss = JavaImpl.createServerSocket(this);
566 return getSSLWrapperFactory().wrap(ss, this);
567 }
568
569 /**
570 * Attempts to get a new socket connection to the given host within the
571 * given time limit.
572 *
573 * @param localHost the local host name/IP to bind against (null == ANY)
574 * @param port the port to listen on
575 * @param backlog number of connections allowed to queue up for accept().
576 * @return SSLServerSocket a new server socket
577 * @throws IOException if an I/O error occurs while creating thesocket
578 */
579 public ServerSocket createServerSocket(int port, int backlog,
580 InetAddress localHost)
581 throws IOException {
582 SSLServerSocketFactory f = getSSLServerSocketFactory();
583 ServerSocket ss = f.createServerSocket(port, backlog, localHost);
584 SSLServerSocket s = (SSLServerSocket) ss;
585 doPreConnectServerSocketStuff(s);
586 return getSSLWrapperFactory().wrap(s, this);
587 }
588
589 public void doPreConnectServerSocketStuff(SSLServerSocket s)
590 throws IOException {
591 if (soTimeout > 0) {
592 s.setSoTimeout(soTimeout);
593 }
594 if (enabledProtocols != null) {
595 JavaImpl.setEnabledProtocols(s, enabledProtocols);
596 }
597 if (enabledCiphers != null) {
598 s.setEnabledCipherSuites(enabledCiphers);
599 }
600
601 /*
602 setNeedClientAuth( false ) has an annoying side effect: it seems to
603 reset setWantClient( true ) back to to false. So I do things this
604 way to make sure setting things "true" happens after setting things
605 "false" - giving "true" priority.
606 */
607 if (!wantClientAuth) {
608 JavaImpl.setWantClientAuth(s, wantClientAuth);
609 }
610 if (!needClientAuth) {
611 s.setNeedClientAuth(needClientAuth);
612 }
613 if (wantClientAuth) {
614 JavaImpl.setWantClientAuth(s, wantClientAuth);
615 }
616 if (needClientAuth) {
617 s.setNeedClientAuth(needClientAuth);
618 }
619 }
620
621 public SSLSocketFactory getSSLSocketFactory() {
622 if (sslContext == null) {
623 initThrowRuntime();
624 }
625 if (socketFactory == null) {
626 socketFactory = JavaImpl.getSSLSocketFactory(sslContext);
627 }
628 return socketFactory;
629 }
630
631 public SSLServerSocketFactory getSSLServerSocketFactory() {
632 if (sslContext == null) {
633 initThrowRuntime();
634 }
635 if (serverSocketFactory == null) {
636 serverSocketFactory = JavaImpl.getSSLServerSocketFactory(sslContext);
637 }
638 return serverSocketFactory;
639 }
640
641 public int getConnectTimeout() {
642 return connectTimeout;
643 }
644
645 public String[] getDefaultCipherSuites() {
646 return getSSLSocketFactory().getDefaultCipherSuites();
647 }
648
649 public String[] getSupportedCipherSuites() {
650 String[] s = new String[SUPPORTED_CIPHERS.length];
651 System.arraycopy(SUPPORTED_CIPHERS, 0, s, 0, s.length);
652 return s;
653 }
654
655 public TrustChain getTrustChain() {
656 return trustChain;
657 }
658
659 public void setCurrentServerChain(X509Certificate[] chain) {
660 this.currentServerChain = chain;
661 }
662
663 public void setCurrentClientChain(X509Certificate[] chain) {
664 this.currentClientChain = chain;
665 }
666
667 public X509Certificate[] getCurrentServerChain() {
668 return currentServerChain;
669 }
670
671 public X509Certificate[] getCurrentClientChain() {
672 return currentClientChain;
673 }
674
675 public static void main(String[] args) {
676 for (int i = 0; i < SUPPORTED_CIPHERS.length; i++) {
677 System.out.println(SUPPORTED_CIPHERS[i]);
678 }
679 System.out.println();
680 System.out.println("----------------------------------------------");
681 addCipher(null, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, true);
682 addCipher(null, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, true);
683 addCipher(null, SSL_RSA_WITH_3DES_EDE_CBC_SHA, true);
684 addCipher(null, SSL_RSA_WITH_RC4_128_SHA, true);
685 addCipher(null, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, true);
686 addCipher(null, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, true);
687 addCipher(null, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, true);
688 addCipher(null, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, true);
689 addCipher(null, TLS_RSA_WITH_AES_128_CBC_SHA, true);
690 addCipher(null, TLS_RSA_WITH_AES_256_CBC_SHA, true);
691 }
692
693 private static void addCipher(List l, String c, boolean printOnStandardOut) {
694 boolean supported = false;
695 if (c != null && SUPPORTED_CIPHERS_SET.contains(c)) {
696 if (l != null) {
697 l.add(c);
698 }
699 supported = true;
700 }
701 if (printOnStandardOut) {
702 System.out.println(c + ":\t" + supported);
703 }
704 }
705
706
707 }