public byte[] getExportData(KgkManager kgkManager) { kgkManager.freshIv2(); kgkManager.freshSalt2(); byte[] kgkBlock = kgkManager.getEncryptedKgk(); Crypter settingsCrypter = this.getSettingsCrypter(kgkManager); byte[] encryptedSettings = settingsCrypter.encrypt(Packer.compress(this.getSettingsAsJSON().toString())); byte[] salt = kgkManager.getKgkCrypterSalt(); byte[] exportData = new byte[1 + salt.length + kgkBlock.length + encryptedSettings.length]; exportData[0] = 0x01; System.arraycopy(salt, 0, exportData, 1, salt.length); System.arraycopy(kgkBlock, 0, exportData, 1 + salt.length, kgkBlock.length); System.arraycopy( encryptedSettings, 0, exportData, 1 + salt.length + kgkBlock.length, encryptedSettings.length); return exportData; }
public void storeLocalSettings(KgkManager kgkManager) { kgkManager.freshSalt2(); kgkManager.freshIv2(); Crypter settingsCrypter = this.getSettingsCrypter(kgkManager); JSONObject storeStructure = new JSONObject(); try { storeStructure.put("settings", this.getSettingsAsJSON()); storeStructure.put("synced", this.getSyncedSettings()); } catch (JSONException jsonError) { Log.d("Settings saving error", "Could not construct JSON structure for storage."); jsonError.printStackTrace(); } SharedPreferences.Editor savedDomainsEditor = savedDomains.edit(); if (settingsCrypter != null) { byte[] encryptedSettings = settingsCrypter.encrypt(Packer.compress(storeStructure.toString())); savedDomainsEditor.putString( "encryptedSettings", Base64.encodeToString(encryptedSettings, Base64.DEFAULT)); savedDomainsEditor.apply(); kgkManager.storeLocalKgkBlock(); } }
public void loadLocalSettings(KgkManager kgkManager) throws WrongPasswordException { Crypter settingsCrypter = this.getSettingsCrypter(kgkManager); byte[] encrypted = Base64.decode(this.savedDomains.getString("encryptedSettings", ""), Base64.DEFAULT); if (encrypted.length < 40) { return; } byte[] decrypted = settingsCrypter.decrypt(encrypted); if (decrypted.length < 40) { throw new WrongPasswordException("wrong length: too short"); } String decompressedSettings = Packer.decompress(decrypted); if (decompressedSettings.length() <= 0) { throw new WrongPasswordException("unable to decompress"); } try { JSONObject decryptedObject = new JSONObject(decompressedSettings); JSONObject decryptedSettings = decryptedObject.getJSONObject("settings"); JSONArray syncedSettings = decryptedObject.getJSONArray("synced"); Iterator<String> keys = decryptedSettings.keys(); while (keys.hasNext()) { String key = keys.next(); JSONObject settingObject = decryptedSettings.getJSONObject(key); boolean found = false; for (PasswordSetting setting : this.settings) { if (setting.getDomain().contentEquals(key)) { found = true; DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH); Date modifiedRemote = df.parse(settingObject.getString("mDate")); if (modifiedRemote.after(setting.getMDate())) { setting.loadFromJSON(settingObject); boolean foundInSynced = false; for (int i = 0; i < syncedSettings.length(); i++) { if (syncedSettings.getString(i).contentEquals(key)) { foundInSynced = true; } } setting.setSynced(foundInSynced); } } } if (!found) { PasswordSetting newSetting = new PasswordSetting(key); newSetting.loadFromJSON(settingObject); boolean foundInSynced = false; for (int i = 0; i < syncedSettings.length(); i++) { if (syncedSettings.getString(i).contentEquals(key)) { foundInSynced = true; } } newSetting.setSynced(foundInSynced); this.settings.add(newSetting); } } } catch (JSONException jsonError) { Log.d("Settings loading error", "The loaded settings are not in JSON format."); jsonError.printStackTrace(); } catch (ParseException timeFormatError) { Log.d( "Settings loading error", "The loaded settings contain time information in a wrong format."); timeFormatError.printStackTrace(); } }
public boolean updateFromExportData(KgkManager kgkManager, byte[] blob) { if (!(blob[0] == 0x01)) { Log.d("Version error", "Wrong data format. Could not import anything."); return true; } byte[] encryptedSettings = Arrays.copyOfRange(blob, 145, blob.length); Crypter settingsCrypter = this.getSettingsCrypter(kgkManager); byte[] decryptedSettings = settingsCrypter.decrypt(encryptedSettings); if (decryptedSettings.length <= 0) { Toast.makeText(contentContext, R.string.sync_wrong_password, Toast.LENGTH_SHORT).show(); return false; } String jsonString = Packer.decompress(decryptedSettings); try { JSONObject loadedSettings = new JSONObject(jsonString); boolean updateRemote = false; Iterator<String> loadedSettingsIterator = loadedSettings.keys(); while (loadedSettingsIterator.hasNext()) { JSONObject loadedSetting = loadedSettings.getJSONObject(loadedSettingsIterator.next()); boolean found = false; for (String domain : this.getDomainList()) { PasswordSetting setting = this.getSetting(domain); if (setting.getDomain().equals(loadedSetting.getString("domain"))) { found = true; DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH); Date modifiedRemote = df.parse(loadedSetting.getString("mDate")); if (modifiedRemote.after(setting.getMDate())) { setting.loadFromJSON(loadedSetting); this.setSetting(setting); } else { updateRemote = true; } setting.setSynced(true); break; } } if (!found) { PasswordSetting newSetting = new PasswordSetting(loadedSetting.getString("domain")); newSetting.loadFromJSON(loadedSetting); newSetting.setSynced(true); this.setSetting(newSetting); } } for (String domain : this.getDomainList()) { PasswordSetting setting = this.getSetting(domain); boolean found = false; Iterator<String> loadedSettingsIterator2 = loadedSettings.keys(); while (loadedSettingsIterator2.hasNext()) { JSONObject loadedSetting = loadedSettings.getJSONObject(loadedSettingsIterator2.next()); if (setting.getDomain().equals(loadedSetting.getString("domain"))) { found = true; break; } } if (!found && setting.isSynced()) { updateRemote = true; } } this.storeLocalSettings(kgkManager); return updateRemote; } catch (JSONException e) { Log.d("Update settings error", "Unable to read JSON data."); e.printStackTrace(); return false; } catch (ParseException e) { Log.d("Update settings error", "Unable to parse the date."); e.printStackTrace(); return false; } }