From abe77dce9111b0130671c1388a1f5608fe7a8435 Mon Sep 17 00:00:00 2001 From: Danilo Del Busso Date: Sun, 21 Mar 2021 01:14:39 +0100 Subject: [PATCH] Switch to encrypted DatabaseManager --- app/debug/output-metadata.json | 18 ----- .../java/com/prj/app/DatabaseManager.java | 67 +++++++++++++------ .../java/com/prj/app/DummyUploadWorker.java | 2 +- .../main/java/com/prj/app/ExposureWorker.java | 2 +- .../java/com/prj/app/SettingsActivity.java | 2 +- .../java/com/prj/app/UploadDataActivity.java | 2 +- .../main/java/com/prj/app/WifiScanner.java | 2 +- .../java/com/prj/app/WifiScanningService.java | 2 +- app/src/main/res/values/strings.xml | 1 + 9 files changed, 53 insertions(+), 45 deletions(-) delete mode 100644 app/debug/output-metadata.json diff --git a/app/debug/output-metadata.json b/app/debug/output-metadata.json deleted file mode 100644 index 8167005..0000000 --- a/app/debug/output-metadata.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": 2, - "artifactType": { - "type": "APK", - "kind": "Directory" - }, - "applicationId": "com.example.prj_android_app", - "variantName": "processDebugResources", - "elements": [ - { - "type": "SINGLE", - "filters": [], - "versionCode": 1, - "versionName": "1.0", - "outputFile": "app-debug.apk" - } - ] -} \ No newline at end of file diff --git a/app/src/main/java/com/prj/app/DatabaseManager.java b/app/src/main/java/com/prj/app/DatabaseManager.java index 3a31644..0fed215 100644 --- a/app/src/main/java/com/prj/app/DatabaseManager.java +++ b/app/src/main/java/com/prj/app/DatabaseManager.java @@ -3,8 +3,6 @@ import android.annotation.SuppressLint; import android.content.Context; import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; import android.location.Location; import android.net.wifi.ScanResult; import android.util.Log; @@ -13,9 +11,14 @@ import com.google.android.gms.maps.model.LatLng; +import net.sqlcipher.database.SQLiteDatabase; +import net.sqlcipher.database.SQLiteOpenHelper; + import org.json.JSONArray; import org.json.JSONObject; +import java.io.IOException; +import java.security.GeneralSecurityException; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -23,7 +26,7 @@ import java.util.Date; import java.util.List; -@SuppressLint("SimpleDateFormat") +@SuppressLint({"StaticFieldLeak", "SimpleDateFormat"}) public class DatabaseManager extends SQLiteOpenHelper { private static final String SCAN_RESULT_TAB = "SCAN_RESULT_TAB"; private static final String COLUMN_ID = "ID"; @@ -32,25 +35,32 @@ public class DatabaseManager extends SQLiteOpenHelper { private static final String SETTINGS_TAB = "SETTINGS_TAB"; private static final String LOCATION_TAB = "LOCATION_TAB"; private static final int COORDINATES_PRECISION = 5; + private static final String DB_PATH = "prj-app-db.db"; + private static DatabaseManager instance; + + private final Context context; - public DatabaseManager(@Nullable Context context) { - super(context, "prj-app-db.db", null, 1); + private DatabaseManager(@Nullable Context context) { + super(context, DB_PATH, null, 1); + this.context = context; + InitializeSQLCipher(); + } + + public static DatabaseManager getInstance(Context context) { + if (instance == null) { + instance = new DatabaseManager(context); + } + return instance; } @Override public void onCreate(SQLiteDatabase db) { String createTableStatement = String.format("CREATE TABLE %s (\n\t%s INTEGER PRIMARY KEY AUTOINCREMENT,\n\t%s TEXT NOT NULL\n)", SCAN_RESULT_TAB, COLUMN_ID, COLUMN_TIMESTAMP); - db.execSQL(createTableStatement); - createTableStatement = String.format("CREATE TABLE %s (\n\t ID INTEGER PRIMARY KEY AUTOINCREMENT,\n\t SCAN_RESULT_ID INTEGER NOT NULL,\n\t BSSID TEXT NOT NULL,\n\t DISTANCE NUMERIC NOT NULL\n);", BSSID_SCAN_TAB); - db.execSQL(createTableStatement); - createTableStatement = String.format("CREATE TABLE %s (\n\t NAME TEXT PRIMARY KEY,\n\t VALUE TEXT NOT NULL \n);", SETTINGS_TAB); - db.execSQL(createTableStatement); - createTableStatement = String.format("CREATE TABLE %s (\n\t bssid TEXT PRIMARY KEY,\n\t lat NUMBER NOT NULL, \n\t lng NUMBER NOT NULL \n);", LOCATION_TAB); db.execSQL(createTableStatement); @@ -58,14 +68,29 @@ public void onCreate(SQLiteDatabase db) { db.execSQL(insertSettingsQuery); } + /** + * Initialise an encrypted SQLite database if it doesn't exist + */ + private void InitializeSQLCipher() { + try { + CryptoManager.generateDatabasePassword(context); + } catch (GeneralSecurityException | IOException e) { + e.printStackTrace(); + } + SQLiteDatabase.loadLibs(context); + String databaseFile = context.getDatabasePath(DB_PATH).getPath(); + SQLiteDatabase.openOrCreateDatabase(databaseFile, CryptoManager.getDatabasePassword(context), null); + } + + @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { } public void addLocationData(List results, Location location) { - SQLiteDatabase readableDb = this.getReadableDatabase(); - SQLiteDatabase writeableDb = this.getWritableDatabase(); + SQLiteDatabase readableDb = this.getReadableDatabase(CryptoManager.getDatabasePassword(context)); + SQLiteDatabase writeableDb = this.getWritableDatabase(CryptoManager.getDatabasePassword(context)); for (ScanResult result : results) { @@ -100,7 +125,7 @@ public void addLocationData(List results, Location location) { } public void deleteData() { - SQLiteDatabase db = this.getWritableDatabase(); + SQLiteDatabase db = this.getWritableDatabase(CryptoManager.getDatabasePassword(context)); db.execSQL(String.format("DELETE FROM %s;", BSSID_SCAN_TAB)); db.execSQL(String.format("DELETE FROM %s;", SCAN_RESULT_TAB)); } @@ -115,7 +140,7 @@ public void addScan(List scanList) { return; } String isoTimestamp = ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT); - SQLiteDatabase db = this.getWritableDatabase(); //locking database when using writable + SQLiteDatabase db = this.getWritableDatabase(CryptoManager.getDatabasePassword(context)); //locking database when using writable db.execSQL("INSERT INTO SCAN_RESULT_TAB (" + COLUMN_TIMESTAMP + ") VALUES ('" + isoTimestamp + "');"); //INSERT NEW SCAN RESULT ID AND TIMESTAMP int lastScanResultId = getLastScanResultId(db); StringBuilder queryString = new StringBuilder(); @@ -151,7 +176,7 @@ public int getLastScanResultId(SQLiteDatabase db) { public List getScanBSSIDs() { ArrayList results = new ArrayList<>(); - SQLiteDatabase db = this.getReadableDatabase(); + SQLiteDatabase db = this.getReadableDatabase(CryptoManager.getDatabasePassword(context)); String query = "SELECT DISTINCT B.BSSID\n" + "FROM " + BSSID_SCAN_TAB + " B\n" + " INNER JOIN " + SCAN_RESULT_TAB + " A\n" + @@ -175,7 +200,7 @@ public List getScanBSSIDs() { public List getRawScanData() { ArrayList results = new ArrayList<>(); - SQLiteDatabase db = this.getReadableDatabase(); + SQLiteDatabase db = this.getReadableDatabase(CryptoManager.getDatabasePassword(context)); String query = "SELECT B.BSSID, B.DISTANCE, A.TIMESTAMP \n" + "FROM " + BSSID_SCAN_TAB + " B\n" + " INNER JOIN " + SCAN_RESULT_TAB + " A\n" + @@ -199,7 +224,7 @@ public List getRawScanData() { public JSONArray getRawLocationData() { JSONArray results = new JSONArray(); - SQLiteDatabase db = this.getReadableDatabase(); + SQLiteDatabase db = this.getReadableDatabase(CryptoManager.getDatabasePassword(context)); String query = String.format("SELECT * FROM %s", LOCATION_TAB); Cursor cursor = db.rawQuery(query, null); cursor.moveToFirst(); @@ -221,7 +246,7 @@ public JSONArray getRawLocationData() { public List getScanData() { ArrayList results = new ArrayList<>(); - SQLiteDatabase db = this.getReadableDatabase(); + SQLiteDatabase db = this.getReadableDatabase(CryptoManager.getDatabasePassword(context)); String query = "SELECT DISTINCT B.BSSID, B.DISTANCE, A.TIMESTAMP \n" + "FROM " + BSSID_SCAN_TAB + " B\n" + " INNER JOIN " + SCAN_RESULT_TAB + " A\n" + @@ -248,13 +273,13 @@ public List getScanData() { public void setSaveHotspotLocation(boolean value) { int valueToInsert = value ? 1 : 0; String query = "UPDATE " + SETTINGS_TAB + " SET VALUE = " + value + " WHERE NAME = 'SAVE_HOTSPOT_LOCATION'"; - SQLiteDatabase db = this.getWritableDatabase(); + SQLiteDatabase db = this.getWritableDatabase(CryptoManager.getDatabasePassword(context)); db.execSQL(query); } public boolean canSaveHotspotLocation() { ArrayList results = new ArrayList<>(); - SQLiteDatabase db = this.getReadableDatabase(); + SQLiteDatabase db = this.getReadableDatabase(CryptoManager.getDatabasePassword(context)); String query = "SELECT VALUE FROM SETTINGS_TAB WHERE NAME = 'SAVE_HOTSPOT_LOCATION'"; Cursor cursor = db.rawQuery(query, null); cursor.moveToFirst(); diff --git a/app/src/main/java/com/prj/app/DummyUploadWorker.java b/app/src/main/java/com/prj/app/DummyUploadWorker.java index 78038ca..0d59635 100644 --- a/app/src/main/java/com/prj/app/DummyUploadWorker.java +++ b/app/src/main/java/com/prj/app/DummyUploadWorker.java @@ -32,7 +32,7 @@ public DummyUploadWorker( @Override public @NotNull Result doWork() { - DatabaseManager databaseManager = new DatabaseManager(getApplicationContext()); + DatabaseManager databaseManager = DatabaseManager.getInstance(getApplicationContext()); List results = databaseManager.getRawScanData(); //get the actual data in order to have consistent request sizes //create dummy data for (String[] row : results) { diff --git a/app/src/main/java/com/prj/app/ExposureWorker.java b/app/src/main/java/com/prj/app/ExposureWorker.java index b9f1e8d..50dd07a 100644 --- a/app/src/main/java/com/prj/app/ExposureWorker.java +++ b/app/src/main/java/com/prj/app/ExposureWorker.java @@ -20,7 +20,7 @@ public ExposureWorker( public @NotNull Result doWork() { // Do the work here--in this case, upload the images. Log.d("wifi", "Starting Exposure Check"); - BSSIDMatcher bssidMatcher = new BSSIDMatcher(new DatabaseManager(getApplicationContext()), null, getApplicationContext()); + BSSIDMatcher bssidMatcher = new BSSIDMatcher(DatabaseManager.getInstance(getApplicationContext()), null, getApplicationContext()); bssidMatcher.getMatchingBSSIDs(); //this will take care of sending a notification return Result.success(); } diff --git a/app/src/main/java/com/prj/app/SettingsActivity.java b/app/src/main/java/com/prj/app/SettingsActivity.java index 1a62ec7..f3e5bef 100644 --- a/app/src/main/java/com/prj/app/SettingsActivity.java +++ b/app/src/main/java/com/prj/app/SettingsActivity.java @@ -34,7 +34,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Objects.requireNonNull(getSupportActionBar()).hide(); setContentView(R.layout.activity_settings); - databaseManager = new DatabaseManager(this); + databaseManager = DatabaseManager.getInstance(getApplicationContext()); bssidMatcher = new BSSIDMatcher(databaseManager, findViewById(R.id.resultTextView), this.getApplicationContext()); diff --git a/app/src/main/java/com/prj/app/UploadDataActivity.java b/app/src/main/java/com/prj/app/UploadDataActivity.java index ccc5efe..04877ef 100644 --- a/app/src/main/java/com/prj/app/UploadDataActivity.java +++ b/app/src/main/java/com/prj/app/UploadDataActivity.java @@ -38,7 +38,7 @@ protected void onCreate(Bundle savedInstanceState) { public void uploadScans(View view) { toggleLoading(); - DatabaseManager databaseManager = new DatabaseManager(getApplicationContext()); + DatabaseManager databaseManager = DatabaseManager.getInstance(getApplicationContext()); boolean canUploadLocation = ((Switch) findViewById(R.id.uploadLocationDataSwitch)).isChecked(); JSONArray locationData = canUploadLocation ? databaseManager.getRawLocationData() : new JSONArray(); diff --git a/app/src/main/java/com/prj/app/WifiScanner.java b/app/src/main/java/com/prj/app/WifiScanner.java index e282fa1..c244fb4 100644 --- a/app/src/main/java/com/prj/app/WifiScanner.java +++ b/app/src/main/java/com/prj/app/WifiScanner.java @@ -38,7 +38,7 @@ public void onReceive(Context c, Intent intent) { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); context.registerReceiver(wifiScanReceiver, intentFilter); - databaseManager = new DatabaseManager(context); + databaseManager = DatabaseManager.getInstance(context.getApplicationContext()); } public void startScan(Location location) { diff --git a/app/src/main/java/com/prj/app/WifiScanningService.java b/app/src/main/java/com/prj/app/WifiScanningService.java index c03db1b..b7f4b77 100644 --- a/app/src/main/java/com/prj/app/WifiScanningService.java +++ b/app/src/main/java/com/prj/app/WifiScanningService.java @@ -44,7 +44,7 @@ public void onCreate() { @Override public int onStartCommand(Intent intent, int flags, int startId) { this.intent = intent; - databaseManager = new DatabaseManager(getApplicationContext()); + databaseManager = DatabaseManager.getInstance(getApplicationContext()); if (notification == null) { createNotificationChannel(); Intent notificationIntent = new Intent(this, MainActivity.class); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f762636..427f3cb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,4 +8,5 @@ Upload All Scan Data I also want to upload all my location data Yes, I want to upload my data + com.prj.app.PREFERENCE_FILE_KEY \ No newline at end of file