From 5b402478e986a0883dee433ca2fe5f23e6365193 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Mon, 16 May 2016 22:29:10 -0400 Subject: [PATCH] Use encrypted connection to server (TLS) --- app/src/main/assets/cacert.pem | 41 +++++++++++ .../org/isoron/uhabits/sync/SyncManager.java | 73 +++++++++++++++---- 2 files changed, 101 insertions(+), 13 deletions(-) create mode 100644 app/src/main/assets/cacert.pem diff --git a/app/src/main/assets/cacert.pem b/app/src/main/assets/cacert.pem new file mode 100644 index 000000000..e7dfc8294 --- /dev/null +++ b/app/src/main/assets/cacert.pem @@ -0,0 +1,41 @@ +-----BEGIN CERTIFICATE----- +MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290 +IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB +IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA +Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO +BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi +MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ +ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ +8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6 +zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y +fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7 +w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc +G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k +epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q +laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ +QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU +fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826 +YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w +ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY +gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe +MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0 +IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy +dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw +czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0 +dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl +aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC +AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg +b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB +ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc +nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg +18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c +gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl +Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY +sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T +SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF +CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum +GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk +zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW +omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD +-----END CERTIFICATE----- diff --git a/app/src/main/java/org/isoron/uhabits/sync/SyncManager.java b/app/src/main/java/org/isoron/uhabits/sync/SyncManager.java index dfddc89c2..c6c42ce40 100644 --- a/app/src/main/java/org/isoron/uhabits/sync/SyncManager.java +++ b/app/src/main/java/org/isoron/uhabits/sync/SyncManager.java @@ -32,11 +32,18 @@ import org.isoron.uhabits.helpers.DatabaseHelper; import org.json.JSONException; import org.json.JSONObject; +import java.io.InputStream; import java.net.URISyntaxException; +import java.security.KeyStore; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; import java.util.Date; import java.util.LinkedList; import java.util.List; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; + import io.socket.client.IO; import io.socket.client.Socket; import io.socket.emitter.Emitter; @@ -50,7 +57,7 @@ public class SyncManager public static final String EVENT_FETCH = "fetch"; public static final String EVENT_FETCH_OK = "fetchOK"; - public static final String SYNC_SERVER_URL = "http://sync.loophabits.org:4000"; + public static final String SYNC_SERVER_URL = "https://sync.loophabits.org:4000"; private static String GROUP_KEY; private static String CLIENT_ID; @@ -75,6 +82,8 @@ public class SyncManager try { + IO.setDefaultSSLContext(getCACertSSLContext()); + socket = IO.socket(SYNC_SERVER_URL); logSocketEvent(socket, Socket.EVENT_CONNECT, "Connected"); @@ -100,7 +109,34 @@ public class SyncManager } catch (URISyntaxException e) { - throw new RuntimeException(e.getMessage()); + throw new RuntimeException(e); + } + } + + private SSLContext getCACertSSLContext() + { + try + { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + InputStream caInput = activity.getAssets().open("cacert.pem"); + Certificate ca = cf.generateCertificate(caInput); + + KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); + ks.load(null, null); + ks.setCertificateEntry("ca", ca); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance( + TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(ks); + + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(null, tmf.getTrustManagers(), null); + + return ctx; + } + catch (Exception e) + { + throw new RuntimeException(e); } } @@ -170,7 +206,7 @@ public class SyncManager } catch (JSONException e) { - throw new RuntimeException(e.getMessage()); + throw new RuntimeException(e); } } } @@ -190,15 +226,10 @@ public class SyncManager } catch (JSONException e) { - throw new RuntimeException(e.getMessage()); + throw new RuntimeException(e); } } - private void updateLastSync(Long timestamp) - { - prefs.edit().putLong("lastSync", timestamp).apply(); - } - private void executeCommand(JSONObject root) throws JSONException { Command received = CommandParser.fromJSON(root); @@ -243,7 +274,7 @@ public class SyncManager } catch (JSONException e) { - throw new RuntimeException(e.getMessage()); + throw new RuntimeException(e); } } } @@ -253,9 +284,20 @@ public class SyncManager @Override public void call(Object... args) { - Log.i("SyncManager", "Fetch OK"); - emitPending(); - readyToEmit = true; + try + { + Log.i("SyncManager", "Fetch OK"); + + JSONObject json = new JSONObject((String) args[0]); + updateLastSync(json.getLong("timestamp")); + + emitPending(); + readyToEmit = true; + } + catch (JSONException e) + { + throw new RuntimeException(e); + } } } @@ -267,4 +309,9 @@ public class SyncManager readyToEmit = false; } } + + private void updateLastSync(Long timestamp) + { + prefs.edit().putLong("lastSync", timestamp).apply(); + } }