|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 package org.mozilla.gecko.sync.net; |
|
6 |
|
7 import java.io.IOException; |
|
8 import java.net.Socket; |
|
9 |
|
10 import javax.net.ssl.SSLContext; |
|
11 import javax.net.ssl.SSLSocket; |
|
12 |
|
13 import org.mozilla.gecko.background.common.log.Logger; |
|
14 |
|
15 import ch.boye.httpclientandroidlib.conn.ssl.SSLSocketFactory; |
|
16 import ch.boye.httpclientandroidlib.params.HttpParams; |
|
17 |
|
18 public class TLSSocketFactory extends SSLSocketFactory { |
|
19 private static final String LOG_TAG = "TLSSocketFactory"; |
|
20 private static final String[] DEFAULT_CIPHER_SUITES = new String[] { |
|
21 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", |
|
22 "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", |
|
23 "SSL_RSA_WITH_RC4_128_SHA", // "RC4_SHA" |
|
24 }; |
|
25 private static final String[] DEFAULT_PROTOCOLS = new String[] { |
|
26 "SSLv3", |
|
27 "TLSv1" |
|
28 }; |
|
29 |
|
30 // Guarded by `this`. |
|
31 private static String[] cipherSuites = DEFAULT_CIPHER_SUITES; |
|
32 |
|
33 public TLSSocketFactory(SSLContext sslContext) { |
|
34 super(sslContext); |
|
35 } |
|
36 |
|
37 /** |
|
38 * Attempt to specify the cipher suites to use for a connection. If |
|
39 * setting fails (as it will on Android 2.2, because the wrong names |
|
40 * are in use to specify ciphers), attempt to set the defaults. |
|
41 * |
|
42 * We store the list of cipher suites in `cipherSuites`, which |
|
43 * avoids this fallback handling having to be executed more than once. |
|
44 * |
|
45 * This method is synchronized to ensure correct use of that member. |
|
46 * |
|
47 * See Bug 717691 for more details. |
|
48 * |
|
49 * @param socket |
|
50 * The SSLSocket on which to operate. |
|
51 */ |
|
52 public static synchronized void setEnabledCipherSuites(SSLSocket socket) { |
|
53 try { |
|
54 socket.setEnabledCipherSuites(cipherSuites); |
|
55 } catch (IllegalArgumentException e) { |
|
56 cipherSuites = socket.getSupportedCipherSuites(); |
|
57 Logger.warn(LOG_TAG, "Setting enabled cipher suites failed: " + e.getMessage()); |
|
58 Logger.warn(LOG_TAG, "Using " + cipherSuites.length + " supported suites."); |
|
59 socket.setEnabledCipherSuites(cipherSuites); |
|
60 } |
|
61 } |
|
62 |
|
63 @Override |
|
64 public Socket createSocket(HttpParams params) throws IOException { |
|
65 SSLSocket socket = (SSLSocket) super.createSocket(params); |
|
66 socket.setEnabledProtocols(DEFAULT_PROTOCOLS); |
|
67 setEnabledCipherSuites(socket); |
|
68 return socket; |
|
69 } |
|
70 } |