Skip to content

Commit eda8e7c

Browse files
committed
Fix FirmwareDownloader.downloadURL() method for Android < 5.0
because GitHub only supports TLSv1.2.
1 parent 033e05c commit eda8e7c

File tree

2 files changed

+104
-25
lines changed

2 files changed

+104
-25
lines changed

src/se/bitcraze/crazyfliecontrol/bootloader/FirmwareDownloader.java

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,17 @@
3030
import java.io.BufferedReader;
3131
import java.io.File;
3232
import java.io.IOException;
33-
import java.io.InputStream;
3433
import java.io.InputStreamReader;
3534
import java.io.PrintWriter;
35+
import java.net.URL;
36+
import java.security.KeyManagementException;
37+
import java.security.NoSuchAlgorithmException;
3638
import java.util.ArrayList;
3739
import java.util.Collections;
3840
import java.util.Iterator;
3941
import java.util.LinkedList;
4042
import java.util.List;
4143

42-
import org.apache.http.HttpEntity;
43-
import org.apache.http.HttpResponse;
44-
import org.apache.http.StatusLine;
45-
import org.apache.http.client.HttpClient;
46-
import org.apache.http.client.methods.HttpGet;
47-
import org.apache.http.impl.client.DefaultHttpClient;
4844
import org.json.JSONArray;
4945
import org.json.JSONException;
5046
import org.json.JSONObject;
@@ -58,10 +54,12 @@
5854
import android.net.NetworkInfo;
5955
import android.net.Uri;
6056
import android.os.AsyncTask;
61-
import android.os.Build;
6257
import android.os.Bundle;
6358
import android.util.Log;
6459
import android.widget.Toast;
60+
61+
import javax.net.ssl.HttpsURLConnection;
62+
6563
import se.bitcraze.crazyflie.lib.bootloader.Bootloader;
6664
import se.bitcraze.crazyflie.lib.bootloader.FirmwareRelease;
6765

@@ -227,11 +225,9 @@ private void downloadFile (String url, String fileName, String tagName) {
227225
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
228226
request.setDescription("Some description");
229227
request.setTitle(fileName);
230-
// in order for this if to run, you must use the android 3.2 to compile your app
231-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
232-
request.allowScanningByMediaScanner();
233-
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
234-
}
228+
// in order for this if to run, you must use android 3.2 (API 11) to compile your app
229+
request.allowScanningByMediaScanner();
230+
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
235231
request.setDestinationInExternalFilesDir(mContext, null, BootloaderActivity.BOOTLOADER_DIR + "/" + tagName + "/" + fileName);
236232

237233
// get download service and enqueue file
@@ -247,31 +243,38 @@ private void downloadFile (String url, String fileName, String tagName) {
247243
private String downloadUrl(String myUrl) throws IOException {
248244
BufferedReader reader = null;
249245
StringBuilder builder = new StringBuilder();
250-
HttpClient client = new DefaultHttpClient();
251-
HttpGet httpGet = new HttpGet(myUrl);
246+
URL url = new URL(myUrl);
247+
248+
// Retrofitting support for TLSv1.2, because GitHub only supports TLSv1.2
252249
try {
253-
HttpResponse response = client.execute(httpGet);
254-
StatusLine statusLine = response.getStatusLine();
255-
int statusCode = statusLine.getStatusCode();
250+
HttpsURLConnection.setDefaultSSLSocketFactory(new TLSSocketFactory());
251+
} catch (KeyManagementException e) {
252+
e.printStackTrace();
253+
} catch (NoSuchAlgorithmException e) {
254+
e.printStackTrace();
255+
}
256+
257+
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
256258

257-
if (statusCode == 200) {
258-
HttpEntity entity = response.getEntity();
259-
InputStream content = entity.getContent();
260-
reader = new BufferedReader(new InputStreamReader(content, "UTF-8"));
259+
try {
260+
String responseMsg = urlConnection.getResponseMessage();
261+
int responseCode = urlConnection.getResponseCode();
261262

263+
if (responseCode == 200) {
264+
reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
262265
String line;
263266
while ((line = reader.readLine()) != null) {
264267
builder.append(line);
265268
}
266269
} else {
267-
Log.d(LOG_TAG, "The response is: " + response);
268-
return "The response is: " + response;
270+
Log.d(LOG_TAG, "The response is: " + responseMsg);
271+
return "The response is: " + responseMsg;
269272
}
270273
} finally {
271-
// Makes sure that the InputStream is closed after the app is finished using it.
272274
if (reader != null) {
273275
reader.close();
274276
}
277+
urlConnection.disconnect();
275278
}
276279
return builder.toString();
277280
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package se.bitcraze.crazyfliecontrol.bootloader;
2+
3+
import java.io.IOException;
4+
import java.net.InetAddress;
5+
import java.net.Socket;
6+
import java.net.UnknownHostException;
7+
import java.security.KeyManagementException;
8+
import java.security.NoSuchAlgorithmException;
9+
10+
import javax.net.ssl.SSLContext;
11+
import javax.net.ssl.SSLSocket;
12+
import javax.net.ssl.SSLSocketFactory;
13+
14+
/**
15+
* @author fkrauthan
16+
*
17+
* https://gist.github.com/fkrauthan/ac8624466a4dee4fd02f#file-tlssocketfactory-java
18+
*
19+
*/
20+
public class TLSSocketFactory extends SSLSocketFactory {
21+
22+
private SSLSocketFactory internalSSLSocketFactory;
23+
24+
public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
25+
SSLContext context = SSLContext.getInstance("TLS");
26+
context.init(null, null, null);
27+
internalSSLSocketFactory = context.getSocketFactory();
28+
}
29+
30+
@Override
31+
public String[] getDefaultCipherSuites() {
32+
return internalSSLSocketFactory.getDefaultCipherSuites();
33+
}
34+
35+
@Override
36+
public String[] getSupportedCipherSuites() {
37+
return internalSSLSocketFactory.getSupportedCipherSuites();
38+
}
39+
40+
@Override
41+
public Socket createSocket() throws IOException {
42+
return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
43+
}
44+
45+
@Override
46+
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
47+
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
48+
}
49+
50+
@Override
51+
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
52+
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
53+
}
54+
55+
@Override
56+
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
57+
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
58+
}
59+
60+
@Override
61+
public Socket createSocket(InetAddress host, int port) throws IOException {
62+
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
63+
}
64+
65+
@Override
66+
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
67+
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
68+
}
69+
70+
private Socket enableTLSOnSocket(Socket socket) {
71+
if(socket != null && (socket instanceof SSLSocket)) {
72+
((SSLSocket) socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
73+
}
74+
return socket;
75+
}
76+
}

0 commit comments

Comments
 (0)