diff --git a/app/src/main/java/lu/circl/mispbump/activities/ExchangeActivity.java b/app/src/main/java/lu/circl/mispbump/activities/ExchangeActivity.java index 561da2e..c23d67d 100644 --- a/app/src/main/java/lu/circl/mispbump/activities/ExchangeActivity.java +++ b/app/src/main/java/lu/circl/mispbump/activities/ExchangeActivity.java @@ -118,7 +118,7 @@ public class ExchangeActivity extends AppCompatActivity { SyncInformation syncInformation = new SyncInformation(); syncInformation.organisation = preferenceManager.getUserOrganisation().toSyncOrganisation(); syncInformation.syncUserAuthkey = new RandomString(40).nextString(); - syncInformation.baseUrl = preferenceManager.getServerUrl(); + syncInformation.baseUrl = preferenceManager.getUserCredentials().first; syncInformation.syncUserPassword = new RandomString(16).nextString(); syncInformation.syncUserEmail = preferenceManager.getUserInfo().email; return syncInformation; diff --git a/app/src/main/java/lu/circl/mispbump/activities/LoginActivity.java b/app/src/main/java/lu/circl/mispbump/activities/LoginActivity.java index 0f649d2..73ac76a 100644 --- a/app/src/main/java/lu/circl/mispbump/activities/LoginActivity.java +++ b/app/src/main/java/lu/circl/mispbump/activities/LoginActivity.java @@ -33,7 +33,7 @@ public class LoginActivity extends AppCompatActivity { private PreferenceManager preferenceManager; private ConstraintLayout constraintLayout; - private TextInputLayout serverAutomationKey; + private TextInputLayout serverAuthkey; private TextInputLayout serverUrl; private ProgressBar progressBar; @@ -81,7 +81,7 @@ public class LoginActivity extends AppCompatActivity { downloadInfoButton.setOnClickListener(onLogin); serverUrl = findViewById(R.id.login_server_url); - serverAutomationKey = findViewById(R.id.login_automation_key); + serverAuthkey = findViewById(R.id.login_automation_key); progressBar = findViewById(R.id.login_progressbar); } @@ -92,12 +92,12 @@ public class LoginActivity extends AppCompatActivity { @Override public void onClick(View v) { final String url = Objects.requireNonNull(serverUrl.getEditText()).getText().toString(); - final String authkey = Objects.requireNonNull(serverAutomationKey.getEditText()).getText().toString(); + final String authkey = Objects.requireNonNull(serverAuthkey.getEditText()).getText().toString(); boolean error = false; serverUrl.setError(null); - serverAutomationKey.setError(null); + serverAuthkey.setError(null); if (!isValidUrl(url)) { error = true; @@ -106,7 +106,7 @@ public class LoginActivity extends AppCompatActivity { if (!isValidAutomationKey(authkey)) { error = true; - serverAutomationKey.setError("Invalid automation key"); + serverAuthkey.setError("Invalid automation key"); } if (error) { @@ -145,14 +145,10 @@ public class LoginActivity extends AppCompatActivity { @Override public void success(Organisation organisation) { preferenceManager.setUserOrgInfo(organisation); - - // save authkey - preferenceManager.setAutomationKey(authkey); - - // save url - preferenceManager.setServerUrl(url); + preferenceManager.setUserCredentials(url, authkey); progressBar.setVisibility(View.GONE); + Intent home = new Intent(getApplicationContext(), HomeActivity.class); startActivity(home); finish(); diff --git a/app/src/main/java/lu/circl/mispbump/activities/ProfileActivity.java b/app/src/main/java/lu/circl/mispbump/activities/ProfileActivity.java index a7dad6e..9ad5cce 100644 --- a/app/src/main/java/lu/circl/mispbump/activities/ProfileActivity.java +++ b/app/src/main/java/lu/circl/mispbump/activities/ProfileActivity.java @@ -17,6 +17,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.util.Pair; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; @@ -48,7 +49,8 @@ public class ProfileActivity extends AppCompatActivity { setContentView(R.layout.activity_profile); preferenceManager = PreferenceManager.getInstance(this); - mispRestClient = MispRestClient.getInstance(preferenceManager.getServerUrl(), preferenceManager.getAuthKey()); + Pair credentials = preferenceManager.getUserCredentials(); + mispRestClient = MispRestClient.getInstance(credentials.first, credentials.second); init(); populateInformationViews(); diff --git a/app/src/main/java/lu/circl/mispbump/activities/StartUpActivity.java b/app/src/main/java/lu/circl/mispbump/activities/StartUpActivity.java index f09df57..3345c3d 100644 --- a/app/src/main/java/lu/circl/mispbump/activities/StartUpActivity.java +++ b/app/src/main/java/lu/circl/mispbump/activities/StartUpActivity.java @@ -2,12 +2,10 @@ package lu.circl.mispbump.activities; import android.content.Intent; import android.os.Bundle; -import android.util.Log; import androidx.appcompat.app.AppCompatActivity; import lu.circl.mispbump.auxiliary.PreferenceManager; -import lu.circl.mispbump.models.restModels.User; /** * Starts either the login or home activity. @@ -32,7 +30,6 @@ public class StartUpActivity extends AppCompatActivity { private boolean isUserLoggedIn() { PreferenceManager preferenceManager = PreferenceManager.getInstance(this); - User user = preferenceManager.getUserInfo(); - return user != null; + return preferenceManager.getUserCredentials() != null && preferenceManager.getUserInfo() != null; } } diff --git a/app/src/main/java/lu/circl/mispbump/activities/UploadActivity.java b/app/src/main/java/lu/circl/mispbump/activities/UploadActivity.java index a4a191b..b7b1550 100644 --- a/app/src/main/java/lu/circl/mispbump/activities/UploadActivity.java +++ b/app/src/main/java/lu/circl/mispbump/activities/UploadActivity.java @@ -9,6 +9,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; +import androidx.core.util.Pair; import com.google.android.material.floatingactionbutton.FloatingActionButton; @@ -99,7 +100,8 @@ public class UploadActivity extends AppCompatActivity { setContentView(R.layout.activity_upload); preferenceManager = PreferenceManager.getInstance(UploadActivity.this); - restClient = MispRestClient.getInstance(preferenceManager.getServerUrl(), preferenceManager.getAuthKey()); + Pair credentials = preferenceManager.getUserCredentials(); + restClient = MispRestClient.getInstance(credentials.first, credentials.second); parseExtra(); initViews(); diff --git a/app/src/main/java/lu/circl/mispbump/auxiliary/MispRestClient.java b/app/src/main/java/lu/circl/mispbump/auxiliary/MispRestClient.java index 02c7515..8c412fb 100644 --- a/app/src/main/java/lu/circl/mispbump/auxiliary/MispRestClient.java +++ b/app/src/main/java/lu/circl/mispbump/auxiliary/MispRestClient.java @@ -61,12 +61,12 @@ public class MispRestClient { return instance; } - public void initMispRestInterface(String url, String authkey) { + private void initMispRestInterface(String url, String authkey) { try { Retrofit retrofit = new Retrofit.Builder() .baseUrl(url) .addConverterFactory(GsonConverterFactory.create()) - .client(getCustomClient(true, false, authkey)) + .client(getCustomClient(true, true, authkey)) .build(); mispRestInterface = retrofit.create(MispRestInterface.class); @@ -370,7 +370,7 @@ public class MispRestClient { if (response.body() != null) { callback.success(response.body().organisation); } else { - callback.failure("Response body was nul"); + callback.failure("Response was empty"); } } } @@ -410,7 +410,6 @@ public class MispRestClient { @Override public void onResponse(@NonNull Call> call, @NonNull Response> response) { if (!response.isSuccessful()) { - // TODO handle return; } @@ -606,6 +605,12 @@ public class MispRestClient { return "Server is not available (no route to host)"; } + try { + throw new Exception(t); + } catch (Exception e) { + e.printStackTrace(); + } + return t.getMessage(); } diff --git a/app/src/main/java/lu/circl/mispbump/auxiliary/PreferenceManager.java b/app/src/main/java/lu/circl/mispbump/auxiliary/PreferenceManager.java index 6bae605..ae2064f 100644 --- a/app/src/main/java/lu/circl/mispbump/auxiliary/PreferenceManager.java +++ b/app/src/main/java/lu/circl/mispbump/auxiliary/PreferenceManager.java @@ -3,6 +3,8 @@ package lu.circl.mispbump.auxiliary; import android.content.Context; import android.content.SharedPreferences; +import androidx.core.util.Pair; + import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @@ -28,9 +30,7 @@ public class PreferenceManager { private static final String PREFERENCES_FILE = "user_settings"; - private static final String SERVER_URL = "server_url"; - private static final String AUTOMATION_KEY = "user_automation"; - + private static final String USER_CREDENTIALS = "user_credentials"; private static final String USER_INFOS = "user_infos"; private static final String USER_ORG_INFOS = "user_org_infos"; @@ -62,6 +62,7 @@ public class PreferenceManager { /** * Save downloaded MISP roles on device. + * * @param roles {@link Role} */ public void setRoles(Role[] roles) { @@ -78,7 +79,8 @@ public class PreferenceManager { * @return {@link Role}[] or null */ public Role[] getRoles() { - Type type = new TypeToken() {}.getType(); + Type type = new TypeToken() { + }.getType(); String rolesString = preferences.getString(MISP_ROLES, ""); assert rolesString != null; @@ -209,147 +211,34 @@ public class PreferenceManager { } - /** - * Encrypts the automation key and stores it in preferences. - * - * @param automationKey key entered in {@link lu.circl.mispbump.activities.LoginActivity} - */ - public void setAutomationKey(String automationKey) { + public void setUserCredentials(String url, String authkey) { try { - KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.AUTOMATION_ALIAS); + KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.USER_CREDENTIALS_ALIAS); SharedPreferences.Editor editor = preferences.edit(); - editor.putString(AUTOMATION_KEY, keyStoreWrapper.encrypt(automationKey)); + editor.putString(USER_CREDENTIALS, keyStoreWrapper.encrypt(new Gson().toJson(new Pair<>(url, authkey)))); editor.apply(); - } catch (NoSuchPaddingException e) { - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (InvalidKeyException e) { - e.printStackTrace(); - } catch (BadPaddingException e) { - e.printStackTrace(); - } catch (IllegalBlockSizeException e) { + } catch (NoSuchAlgorithmException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException e) { e.printStackTrace(); } } - /** - * Decrypts the stored automation key and returns it. - * - * @return decrypted automation key associated with the current user. If no user exists an empty - * String is returned. - */ - public String getAuthKey() { - - if (!preferences.contains(AUTOMATION_KEY)) { - return ""; - } - - try { - KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.AUTOMATION_ALIAS); - return keyStoreWrapper.decrypt(preferences.getString(AUTOMATION_KEY, "")); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (InvalidKeyException e) { - e.printStackTrace(); - } catch (InvalidAlgorithmParameterException e) { - e.printStackTrace(); - } catch (NoSuchPaddingException e) { - e.printStackTrace(); - } catch (BadPaddingException e) { - e.printStackTrace(); - } catch (IllegalBlockSizeException e) { - e.printStackTrace(); - } - - return ""; - } - - /** - * Delete the key to decrypt this entry and the entry itself. - */ - public void clearAutomationKey() { - // remove the key from KeyStore - KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.AUTOMATION_ALIAS); - keyStoreWrapper.deleteStoredKey(); - - SharedPreferences.Editor editor = preferences.edit(); - editor.remove(AUTOMATION_KEY); - editor.apply(); - } - - - /** - * Encrypts the server url and stores it in preferences. - * - * @param serverUrl url of the corresponding misp instance - */ - public void setServerUrl(String serverUrl) { - try { - - KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.SERVER_URL_ALIAS); - SharedPreferences.Editor editor = preferences.edit(); - editor.putString(SERVER_URL, keyStoreWrapper.encrypt(serverUrl)); - editor.apply(); - - } catch (NoSuchPaddingException e) { - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (InvalidKeyException e) { - e.printStackTrace(); - } catch (BadPaddingException e) { - e.printStackTrace(); - } catch (IllegalBlockSizeException e) { - e.printStackTrace(); - } - } - - /** - * Decrypts the stored server url and returns it - * - * @return decrypted misp instance url - */ - public String getServerUrl() { - - if (!preferences.contains(SERVER_URL)) { + public Pair getUserCredentials() { + if (!preferences.contains(USER_CREDENTIALS)) { return null; } try { - KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.SERVER_URL_ALIAS); - return keyStoreWrapper.decrypt(preferences.getString(SERVER_URL, null)); - - } catch (NoSuchPaddingException e) { - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (InvalidAlgorithmParameterException e) { - e.printStackTrace(); - } catch (InvalidKeyException e) { - e.printStackTrace(); - } catch (BadPaddingException e) { - e.printStackTrace(); - } catch (IllegalBlockSizeException e) { + KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.USER_CREDENTIALS_ALIAS); + Type type = new TypeToken>() {}.getType(); + String serializedCreds = keyStoreWrapper.decrypt(preferences.getString(USER_CREDENTIALS, "")); + return new Gson().fromJson(serializedCreds, type); + } catch (InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } - /** - * Delete the key to decrypt this entry and the entry itself. - */ - public void clearServerUrl() { - // remove the key from KeyStore - KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.SERVER_URL_ALIAS); - keyStoreWrapper.deleteStoredKey(); - - SharedPreferences.Editor editor = preferences.edit(); - editor.remove(SERVER_URL); - editor.apply(); - } - private List cachedUploadInformationList; @@ -357,7 +246,8 @@ public class PreferenceManager { KeyStoreWrapper ksw = new KeyStoreWrapper(KeyStoreWrapper.UPLOAD_INFORMATION_ALIAS); String storedUploadInfoString = preferences.getString(UPLOAD_INFO, null); - Type type = new TypeToken>() {}.getType(); + Type type = new TypeToken>() { + }.getType(); if (storedUploadInfoString == null || storedUploadInfoString.isEmpty()) { cachedUploadInformationList = new ArrayList<>(); @@ -462,8 +352,8 @@ public class PreferenceManager { public void clearAllData() { SharedPreferences.Editor editor = preferences.edit(); - clearServerUrl(); - clearAutomationKey(); +// clearServerUrl(); +// clearAutomationKey(); clearUploadInformation(); editor.clear(); diff --git a/app/src/main/java/lu/circl/mispbump/security/KeyStoreWrapper.java b/app/src/main/java/lu/circl/mispbump/security/KeyStoreWrapper.java index 4d2677a..e9a40af 100644 --- a/app/src/main/java/lu/circl/mispbump/security/KeyStoreWrapper.java +++ b/app/src/main/java/lu/circl/mispbump/security/KeyStoreWrapper.java @@ -29,8 +29,7 @@ public class KeyStoreWrapper { public static final String USER_INFO_ALIAS = "ALIAS_USER_INFO"; public static final String USER_ORGANISATION_INFO_ALIAS = "ALIAS_USER_ORGANISATION_INFO"; - public static final String AUTOMATION_ALIAS = "ALIAS_AUTOMATION_KEY"; - public static final String SERVER_URL_ALIAS = "ALIAS_SERVER_URL"; + public static final String USER_CREDENTIALS_ALIAS = "ALIAS_USER_CREDENTIALS"; public static final String UPLOAD_INFORMATION_ALIAS = "ALIAS_UPLOAD_INFORMATION"; private static final String KEYSTORE_PROVIDER = "AndroidKeyStore";