diff --git a/app/src/androidTest/java/com/keepassdroid/tests/TestUtil.java b/app/src/androidTest/java/com/keepassdroid/tests/TestUtil.java
index e54344059..57febad83 100644
--- a/app/src/androidTest/java/com/keepassdroid/tests/TestUtil.java
+++ b/app/src/androidTest/java/com/keepassdroid/tests/TestUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2010 Brian Pellin.
+ * Copyright 2010-2016 Brian Pellin.
*
* This file is part of KeePassDroid.
*
@@ -19,11 +19,16 @@
*/
package com.keepassdroid.tests;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import android.content.Context;
import android.content.res.AssetManager;
+import android.net.Uri;
+
+import com.keepassdroid.utils.EmptyUtils;
+import com.keepassdroid.utils.UriUtil;
public class TestUtil {
@@ -46,4 +51,13 @@ public class TestUtil {
}
+ public static InputStream getKeyFileInputStream(Context ctx, String keyfile) throws FileNotFoundException {
+ InputStream keyIs = null;
+ if (!EmptyUtils.isNullOrEmpty(keyfile)) {
+ Uri uri = UriUtil.parseDefaultFile(keyfile);
+ keyIs = UriUtil.getUriInputStream(ctx, uri);
+ }
+
+ return keyIs;
+ }
}
diff --git a/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb3.java b/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb3.java
index 0fd2f03e7..10e3c6bb3 100644
--- a/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb3.java
+++ b/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb3.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2010 Brian Pellin.
+ * Copyright 2010-2016 Brian Pellin.
*
* This file is part of KeePassDroid.
*
@@ -21,11 +21,13 @@ package com.keepassdroid.tests.database;
import android.content.Context;
import android.content.res.AssetManager;
+import android.net.Uri;
import android.os.Environment;
import android.test.AndroidTestCase;
import com.keepassdroid.database.load.ImporterV3;
import com.keepassdroid.tests.TestUtil;
+import com.keepassdroid.utils.UriUtil;
import java.io.InputStream;
import java.io.File;
@@ -44,7 +46,7 @@ public class Kdb3 extends AndroidTestCase {
InputStream is = am.open(dbAsset, AssetManager.ACCESS_STREAMING);
ImporterV3 importer = new ImporterV3();
- importer.openDatabase(is, password, keyPath);
+ importer.openDatabase(is, password, TestUtil.getKeyFileInputStream(ctx, keyPath));
is.close();
}
diff --git a/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb3Twofish.java b/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb3Twofish.java
index 0a837ccdf..fbce258ce 100644
--- a/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb3Twofish.java
+++ b/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb3Twofish.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2010 Brian Pellin.
+ * Copyright 2010-2016 Brian Pellin.
*
* This file is part of KeePassDroid.
*
@@ -38,7 +38,7 @@ public class Kdb3Twofish extends AndroidTestCase {
ImporterV3 importer = new ImporterV3();
- PwDatabaseV3 db = importer.openDatabase(is, "12345", "");
+ PwDatabaseV3 db = importer.openDatabase(is, "12345", null);
assertTrue(db.algorithm == PwEncryptionAlgorithm.Twofish);
diff --git a/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb4.java b/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb4.java
index 926a2329e..259a9a40f 100644
--- a/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb4.java
+++ b/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb4.java
@@ -62,7 +62,7 @@ public class Kdb4 extends AndroidTestCase {
InputStream is = am.open("test.kdbx", AssetManager.ACCESS_STREAMING);
ImporterV4 importer = new ImporterV4();
- importer.openDatabase(is, "12345", "");
+ importer.openDatabase(is, "12345", null);
is.close();
@@ -76,7 +76,7 @@ public class Kdb4 extends AndroidTestCase {
InputStream is = am.open("test.kdbx", AssetManager.ACCESS_STREAMING);
ImporterV4 importer = new ImporterV4();
- PwDatabaseV4 db = importer.openDatabase(is, "12345", "");
+ PwDatabaseV4 db = importer.openDatabase(is, "12345", null);
is.close();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
@@ -91,7 +91,7 @@ public class Kdb4 extends AndroidTestCase {
InputStream bis = new ByteArrayInputStream(data);
bis = new CopyInputStream(bis, fos);
importer = new ImporterV4();
- db = importer.openDatabase(bis, "12345", "");
+ db = importer.openDatabase(bis, "12345", null);
bis.close();
fos.close();
@@ -112,7 +112,7 @@ public class Kdb4 extends AndroidTestCase {
InputStream is = am.open("keyfile.kdbx", AssetManager.ACCESS_STREAMING);
ImporterV4 importer = new ImporterV4();
- importer.openDatabase(is, "12345", "/sdcard/key");
+ importer.openDatabase(is, "12345", TestUtil.getKeyFileInputStream(ctx,"/sdcard/key"));
is.close();
@@ -125,7 +125,7 @@ public class Kdb4 extends AndroidTestCase {
InputStream is = am.open("key-only.kdbx", AssetManager.ACCESS_STREAMING);
ImporterV4 importer = new ImporterV4();
- importer.openDatabase(is, "", "/sdcard/key");
+ importer.openDatabase(is, "", TestUtil.getKeyFileInputStream(ctx, "/sdcard/key"));
is.close();
@@ -139,7 +139,7 @@ public class Kdb4 extends AndroidTestCase {
InputStream is = am.open("no-encrypt.kdbx", AssetManager.ACCESS_STREAMING);
ImporterV4 importer = new ImporterV4();
- importer.openDatabase(is, "12345", "");
+ importer.openDatabase(is, "12345", null);
is.close();
diff --git a/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb4Header.java b/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb4Header.java
index 6eb5e873c..da50d8b55 100644
--- a/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb4Header.java
+++ b/app/src/androidTest/java/com/keepassdroid/tests/database/Kdb4Header.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2010 Brian Pellin.
+ * Copyright 2010-2016 Brian Pellin.
*
* This file is part of KeePassDroid.
*
@@ -38,7 +38,7 @@ public class Kdb4Header extends AndroidTestCase {
ImporterV4 importer = new ImporterV4();
- PwDatabaseV4 db = importer.openDatabase(is, "12345", "");
+ PwDatabaseV4 db = importer.openDatabase(is, "12345", null);
assertEquals(6000, db.numKeyEncRounds);
diff --git a/app/src/androidTest/java/com/keepassdroid/tests/database/SprEngineTest.java b/app/src/androidTest/java/com/keepassdroid/tests/database/SprEngineTest.java
index 2b9baab00..e7696922e 100644
--- a/app/src/androidTest/java/com/keepassdroid/tests/database/SprEngineTest.java
+++ b/app/src/androidTest/java/com/keepassdroid/tests/database/SprEngineTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Brian Pellin.
+ * Copyright 2014-2016 Brian Pellin.
*
* This file is part of KeePassDroid.
*
@@ -47,7 +47,7 @@ public class SprEngineTest extends AndroidTestCase {
InputStream is = am.open("test.kdbx", AssetManager.ACCESS_STREAMING);
ImporterV4 importer = new ImporterV4();
- db = importer.openDatabase(is, "12345", "");
+ db = importer.openDatabase(is, "12345", null);
is.close();
diff --git a/app/src/androidTest/java/com/keepassdroid/tests/database/TestData.java b/app/src/androidTest/java/com/keepassdroid/tests/database/TestData.java
index eb8609915..88cf2219f 100644
--- a/app/src/androidTest/java/com/keepassdroid/tests/database/TestData.java
+++ b/app/src/androidTest/java/com/keepassdroid/tests/database/TestData.java
@@ -28,6 +28,9 @@ import android.net.Uri;
import com.keepassdroid.Database;
import com.keepassdroid.database.PwDatabaseV3Debug;
import com.keepassdroid.database.load.Importer;
+import com.keepassdroid.tests.TestUtil;
+import com.keepassdroid.utils.EmptyUtils;
+import com.keepassdroid.utils.UriUtil;
public class TestData {
private static final String TEST1_KEYFILE = "";
@@ -54,7 +57,10 @@ public class TestData {
InputStream is = am.open(asset, AssetManager.ACCESS_STREAMING);
Database Db = new Database();
- Db.LoadData(ctx, is, password, keyfile, Importer.DEBUG);
+
+ InputStream keyIs = TestUtil.getKeyFileInputStream(ctx, keyfile);
+
+ Db.LoadData(ctx, is, password, keyIs, Importer.DEBUG);
Uri.Builder b = new Uri.Builder();
Db.mUri = b.scheme("file").path(filename).build();
diff --git a/app/src/main/java/com/keepassdroid/Database.java b/app/src/main/java/com/keepassdroid/Database.java
index d53c9c53f..761abf1ba 100644
--- a/app/src/main/java/com/keepassdroid/Database.java
+++ b/app/src/main/java/com/keepassdroid/Database.java
@@ -31,6 +31,7 @@ import java.io.SyncFailedException;
import java.util.HashSet;
import java.util.Set;
+import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
@@ -44,6 +45,7 @@ import com.keepassdroid.database.load.ImporterFactory;
import com.keepassdroid.database.save.PwDbOutput;
import com.keepassdroid.icons.DrawableFactory;
import com.keepassdroid.search.SearchDbHelper;
+import com.keepassdroid.utils.UriUtil;
/**
* @author bpellin
@@ -68,19 +70,19 @@ public class Database {
loaded = true;
}
- public void LoadData(Context ctx, InputStream is, String password, String keyfile) throws IOException, InvalidDBException {
- LoadData(ctx, is, password, keyfile, new UpdateStatus(), !Importer.DEBUG);
+ public void LoadData(Context ctx, InputStream is, String password, InputStream keyInputStream) throws IOException, InvalidDBException {
+ LoadData(ctx, is, password, keyInputStream, new UpdateStatus(), !Importer.DEBUG);
}
- public void LoadData(Context ctx, Uri uri, String password, String keyfile) throws IOException, FileNotFoundException, InvalidDBException {
+ public void LoadData(Context ctx, Uri uri, String password, Uri keyfile) throws IOException, FileNotFoundException, InvalidDBException {
LoadData(ctx, uri, password, keyfile, new UpdateStatus(), !Importer.DEBUG);
}
- public void LoadData(Context ctx, Uri uri, String password, String keyfile, UpdateStatus status) throws IOException, FileNotFoundException, InvalidDBException {
+ public void LoadData(Context ctx, Uri uri, String password, Uri keyfile, UpdateStatus status) throws IOException, FileNotFoundException, InvalidDBException {
LoadData(ctx, uri, password, keyfile, status, !Importer.DEBUG);
}
- public void LoadData(Context ctx, Uri uri, String password, String keyfile, UpdateStatus status, boolean debug) throws IOException, FileNotFoundException, InvalidDBException {
+ public void LoadData(Context ctx, Uri uri, String password, Uri keyfile, UpdateStatus status, boolean debug) throws IOException, FileNotFoundException, InvalidDBException {
mUri = uri;
readOnly = false;
if (uri.getScheme().equals("file")) {
@@ -88,16 +90,17 @@ public class Database {
readOnly = !file.canWrite();
}
- InputStream is = ctx.getContentResolver().openInputStream(uri);
+ InputStream is = UriUtil.getUriInputStream(ctx, uri);
+ InputStream kfIs = UriUtil.getUriInputStream(ctx, keyfile);
- LoadData(ctx, is, password, keyfile, status, debug);
+ LoadData(ctx, is, password, kfIs, status, debug);
}
- public void LoadData(Context ctx, InputStream is, String password, String keyfile, boolean debug) throws IOException, InvalidDBException {
- LoadData(ctx, is, password, keyfile, new UpdateStatus(), debug);
+ public void LoadData(Context ctx, InputStream is, String password, InputStream kfIs, boolean debug) throws IOException, InvalidDBException {
+ LoadData(ctx, is, password, kfIs, new UpdateStatus(), debug);
}
- public void LoadData(Context ctx, InputStream is, String password, String keyfile, UpdateStatus status, boolean debug) throws IOException, InvalidDBException {
+ public void LoadData(Context ctx, InputStream is, String password, InputStream kfIs, UpdateStatus status, boolean debug) throws IOException, InvalidDBException {
BufferedInputStream bis = new BufferedInputStream(is);
@@ -112,19 +115,19 @@ public class Database {
bis.reset(); // Return to the start
- pm = imp.openDatabase(bis, password, keyfile, status);
+ pm = imp.openDatabase(bis, password, kfIs, status);
if ( pm != null ) {
PwGroup root = pm.rootGroup;
pm.populateGlobals(root);
- LoadData(ctx, pm, password, keyfile, status);
+ LoadData(ctx, pm, password, kfIs, status);
}
loaded = true;
}
- public void LoadData(Context ctx, PwDatabase pm, String password, String keyfile, UpdateStatus status) {
+ public void LoadData(Context ctx, PwDatabase pm, String password, InputStream keyInputStream, UpdateStatus status) {
if ( pm != null ) {
passwordEncodingError = !pm.validatePasswordEncoding(password);
}
@@ -148,7 +151,7 @@ public class Database {
}
public void SaveData(Context ctx, Uri uri) throws IOException, PwDbOutputException {
- if (uri.getScheme().equals("data")) {
+ if (uri.getScheme().equals("file")) {
String filename = uri.getPath();
File tempFile = new File(filename + ".tmp");
FileOutputStream fos = new FileOutputStream(tempFile);
diff --git a/app/src/main/java/com/keepassdroid/PasswordActivity.java b/app/src/main/java/com/keepassdroid/PasswordActivity.java
index 748d16ccd..5a6173e2e 100644
--- a/app/src/main/java/com/keepassdroid/PasswordActivity.java
+++ b/app/src/main/java/com/keepassdroid/PasswordActivity.java
@@ -21,6 +21,7 @@ package com.keepassdroid;
import java.io.File;
import java.io.FileNotFoundException;
+import java.io.InputStream;
import java.net.URLDecoder;
import android.app.Activity;
@@ -33,7 +34,6 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
-import android.os.ParcelFileDescriptor;
import android.preference.PreferenceManager;
import android.text.InputType;
import android.view.Menu;
@@ -61,7 +61,7 @@ import com.keepassdroid.fileselect.BrowserDialog;
import com.keepassdroid.intents.Intents;
import com.keepassdroid.settings.AppSettingsActivity;
import com.keepassdroid.utils.Interaction;
-import com.keepassdroid.utils.StrUtil;
+import com.keepassdroid.utils.UriUtil;
import com.keepassdroid.utils.Util;
public class PasswordActivity extends LockingActivity {
@@ -76,9 +76,10 @@ public class PasswordActivity extends LockingActivity {
private static final int FILE_BROWSE = 256;
public static final int GET_CONTENT = 257;
- private String mFileName;
- private String mKeyFile;
- private Uri mUri = null;
+ //private String mFileName;
+ //private String mKeyFile;
+ private Uri mDbUri = null;
+ private Uri mKeyUri = null;
private boolean mRememberKeyfile;
SharedPreferences prefs;
@@ -123,11 +124,13 @@ public class PasswordActivity extends LockingActivity {
if (resultCode == RESULT_OK) {
String filename = data.getDataString();
if (filename != null) {
+ /*
if (filename.startsWith("file://")) {
filename = filename.substring(7);
}
filename = URLDecoder.decode(filename);
+ */
EditText fn = (EditText) findViewById(R.id.pass_keyfile);
fn.setText(filename);
@@ -182,27 +185,27 @@ public class PasswordActivity extends LockingActivity {
private void retrieveSettings() {
String defaultFilename = prefs.getString(KEY_DEFAULT_FILENAME, "");
- if (mFileName.length() > 0 && mFileName.equals(defaultFilename)) {
+ if (mDbUri.getPath().length() > 0 && UriUtil.equalsDefaultfile(mDbUri, defaultFilename)) {
CheckBox checkbox = (CheckBox) findViewById(R.id.default_database);
checkbox.setChecked(true);
}
}
- private String getKeyFile(String filename) {
+ private Uri getKeyFile(Uri dbUri) {
if ( mRememberKeyfile ) {
- String keyfile = App.getFileHistory().getFileByName(filename);
-
- return keyfile;
+ return App.getFileHistory().getFileByName(dbUri);
} else {
- return "";
+ return null;
}
}
private void populateView() {
- setEditText(R.id.filename, mFileName);
+ String db = (mDbUri == null) ? "" : mDbUri.toString();
+ setEditText(R.id.filename, db);
- setEditText(R.id.pass_keyfile, mKeyFile);
+ String key = (mKeyUri == null) ? "" : mKeyUri.toString();
+ setEditText(R.id.pass_keyfile, key);
}
/*
@@ -226,7 +229,7 @@ public class PasswordActivity extends LockingActivity {
String newDefaultFileName;
if (isChecked) {
- newDefaultFileName = mFileName;
+ newDefaultFileName = mDbUri.toString();
} else {
newDefaultFileName = "";
}
@@ -251,9 +254,13 @@ public class PasswordActivity extends LockingActivity {
}
}
- private void loadDatabase(String pass, String keyfile)
+ private void loadDatabase(String pass, String keyfile) {
+ loadDatabase(pass, UriUtil.parseDefaultFile(keyfile));
+ }
+
+ private void loadDatabase(String pass, Uri keyfile)
{
- if ( pass.length() == 0 && keyfile.length() == 0 ) {
+ if ( pass.length() == 0 && (keyfile == null || keyfile.toString().length() == 0)) {
errorMessage(R.string.error_nopass);
return;
}
@@ -268,19 +275,8 @@ public class PasswordActivity extends LockingActivity {
// Clear the shutdown flag
App.clearShutdown();
- Uri uri;
- if (mUri != null) {
- uri = mUri;
- } else {
- uri = Uri.parse(fileName);
+ Uri uri = UriUtil.parseDefaultFile(fileName);
- String scheme = uri.getScheme();
- if (scheme == null || scheme.equals("")) {
- Uri.Builder builder = new Uri.Builder();
- builder.scheme("file").authority("").path(fileName);
- uri = builder.build();
- }
- }
Handler handler = new Handler();
LoadDB task = new LoadDB(db, PasswordActivity.this, uri, pass, keyfile, new AfterLoad(handler, db));
ProgressTask pt = new ProgressTask(PasswordActivity.this, task, R.string.loading_database);
@@ -365,39 +361,38 @@ public class PasswordActivity extends LockingActivity {
String action = i.getAction();;
if ( action != null && action.equals(VIEW_INTENT) ) {
Uri incoming = i.getData();
+ mDbUri = incoming;
if (incoming.getScheme().equals("file")) {
- mFileName = incoming.getPath();
+ String fileName = incoming.getPath();
- if (mFileName.length() == 0) {
+ if (fileName.length() == 0) {
// No file name
return R.string.FileNotFound;
}
- File dbFile = new File(mFileName);
+ File dbFile = new File(fileName);
if (!dbFile.exists()) {
// File does not exist
return R.string.FileNotFound;
}
- mKeyFile = getKeyFile(mFileName);
+ mKeyUri = getKeyFile(mDbUri);
}
else if (incoming.getScheme().equals("content")) {
- mUri = incoming;
- mFileName = mUri.toString();
- mKeyFile = getKeyFile(mFileName);
+ mKeyUri = getKeyFile(mDbUri);
}
else {
return R.string.error_can_not_handle_uri;
}
} else {
- mFileName = i.getStringExtra(KEY_FILENAME);
- mKeyFile = i.getStringExtra(KEY_KEYFILE);
+ mDbUri = UriUtil.parseDefaultFile(i.getStringExtra(KEY_FILENAME));
+ mKeyUri = UriUtil.parseDefaultFile(i.getStringExtra(KEY_KEYFILE));
password = i.getStringExtra(KEY_PASSWORD);
launch_immediately = i.getBooleanExtra(KEY_LAUNCH_IMMEDIATELY, false);
- if ( mKeyFile == null || mKeyFile.length() == 0) {
- mKeyFile = getKeyFile(mFileName);
+ if ( mKeyUri == null || mKeyUri.toString().length() == 0) {
+ mKeyUri = getKeyFile(mDbUri);
}
}
return null;
@@ -458,12 +453,19 @@ public class PasswordActivity extends LockingActivity {
if (Interaction.isIntentAvailable(PasswordActivity.this, Intents.OPEN_INTENTS_FILE_BROWSE)) {
Intent i = new Intent(Intents.OPEN_INTENTS_FILE_BROWSE);
- if (mFileName.length() > 0) {
- File keyfile = new File(mFileName);
- File parent = keyfile.getParentFile();
- if (parent != null) {
- i.setData(Uri.parse("file://" + parent.getAbsolutePath()));
+ // Get file path parent if possible
+ try {
+ if (mDbUri != null && mDbUri.toString().length() > 0) {
+ if (mDbUri.getScheme().equals("file")) {
+ File keyfile = new File(mDbUri.getPath());
+ File parent = keyfile.getParentFile();
+ if (parent != null) {
+ i.setData(Uri.parse("file://" + parent.getAbsolutePath()));
+ }
+ }
}
+ } catch (Exception e) {
+ // Ignore
}
try {
@@ -485,7 +487,7 @@ public class PasswordActivity extends LockingActivity {
retrieveSettings();
if (launch_immediately)
- loadDatabase(password, mKeyFile);
+ loadDatabase(password, mDbUri);
}
}
}
diff --git a/app/src/main/java/com/keepassdroid/SetPasswordDialog.java b/app/src/main/java/com/keepassdroid/SetPasswordDialog.java
index 3799c9b8b..f8cb753c1 100644
--- a/app/src/main/java/com/keepassdroid/SetPasswordDialog.java
+++ b/app/src/main/java/com/keepassdroid/SetPasswordDialog.java
@@ -21,6 +21,7 @@ package com.keepassdroid;
import android.content.Context;
import android.content.DialogInterface;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
@@ -33,11 +34,13 @@ import com.keepassdroid.app.App;
import com.keepassdroid.database.edit.FileOnFinish;
import com.keepassdroid.database.edit.OnFinish;
import com.keepassdroid.database.edit.SetPassword;
+import com.keepassdroid.utils.EmptyUtils;
+import com.keepassdroid.utils.UriUtil;
public class SetPasswordDialog extends CancelDialog {
private byte[] masterKey;
- private String mKeyfile;
+ private Uri mKeyfile;
private FileOnFinish mFinish;
public SetPasswordDialog(Context context) {
@@ -54,7 +57,7 @@ public class SetPasswordDialog extends CancelDialog {
return masterKey;
}
- public String keyfile() {
+ public Uri keyfile() {
return mKeyfile;
}
@@ -83,11 +86,11 @@ public class SetPasswordDialog extends CancelDialog {
}
TextView keyfileView = (TextView) findViewById(R.id.pass_keyfile);
- String keyfile = keyfileView.getText().toString();
+ Uri keyfile = UriUtil.parseDefaultFile(keyfileView.getText().toString());
mKeyfile = keyfile;
// Verify that a password or keyfile is set
- if ( pass.length() == 0 && keyfile.length() == 0 ) {
+ if ( pass.length() == 0 && EmptyUtils.isNullOrEmpty(keyfile)) {
Toast.makeText(getContext(), R.string.error_nopass, Toast.LENGTH_LONG).show();
return;
diff --git a/app/src/main/java/com/keepassdroid/database/PwDatabase.java b/app/src/main/java/com/keepassdroid/database/PwDatabase.java
index 53c555ba6..3e48db3fa 100644
--- a/app/src/main/java/com/keepassdroid/database/PwDatabase.java
+++ b/app/src/main/java/com/keepassdroid/database/PwDatabase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2015 Brian Pellin.
+ * Copyright 2009-2016 Brian Pellin.
*
* This file is part of KeePassDroid.
*
@@ -20,10 +20,12 @@
package com.keepassdroid.database;
import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
@@ -40,6 +42,7 @@ import com.keepassdroid.crypto.finalkey.FinalKeyFactory;
import com.keepassdroid.database.exception.InvalidKeyFileException;
import com.keepassdroid.database.exception.KeyFileEmptyException;
import com.keepassdroid.stream.NullOutputStream;
+import com.keepassdroid.utils.Util;
public abstract class PwDatabase {
@@ -100,20 +103,20 @@ public abstract class PwDatabase {
}
- public abstract byte[] getMasterKey(String key, String keyFileName) throws InvalidKeyFileException, IOException;
+ public abstract byte[] getMasterKey(String key, InputStream keyInputStream) throws InvalidKeyFileException, IOException;
- public void setMasterKey(String key, String keyFileName)
+ public void setMasterKey(String key, InputStream keyInputStream)
throws InvalidKeyFileException, IOException {
- assert( key != null && keyFileName != null );
+ assert(key != null);
- masterKey = getMasterKey(key, keyFileName);
+ masterKey = getMasterKey(key, keyInputStream);
}
- protected byte[] getCompositeKey(String key, String keyFileName)
+ protected byte[] getCompositeKey(String key, InputStream keyInputStream)
throws InvalidKeyFileException, IOException {
- assert(key != null && keyFileName != null);
+ assert(key != null && keyInputStream != null);
- byte[] fileKey = getFileKey(keyFileName);
+ byte[] fileKey = getFileKey(keyInputStream);
byte[] passwordKey = getPasswordKey(key);
@@ -129,53 +132,32 @@ public abstract class PwDatabase {
return md.digest(fileKey);
}
- protected byte[] getFileKey(String fileName)
+ protected byte[] getFileKey(InputStream keyInputStream)
throws InvalidKeyFileException, IOException {
- assert(fileName != null);
-
- File keyfile = new File(fileName);
-
- if ( ! keyfile.exists() ) {
- throw new InvalidKeyFileException();
- }
-
- byte[] key = loadXmlKeyFile(fileName);
+ assert(keyInputStream != null);
+
+ byte[] key = loadXmlKeyFile(keyInputStream);
if ( key != null ) {
return key;
}
-
- FileInputStream fis;
- try {
- fis = new FileInputStream(keyfile);
- } catch (FileNotFoundException e) {
- throw new InvalidKeyFileException();
- }
-
- BufferedInputStream bis = new BufferedInputStream(fis, 64);
-
- long fileSize = keyfile.length();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ Util.copyStream(keyInputStream, bos);
+ byte[] keyData = bos.toByteArray();
+
+
+ long fileSize = keyData.length;
if ( fileSize == 0 ) {
throw new KeyFileEmptyException();
} else if ( fileSize == 32 ) {
- byte[] outputKey = new byte[32];
- if ( bis.read(outputKey, 0, 32) != 32 ) {
- throw new IOException("Error reading key.");
- }
-
- return outputKey;
+ return keyData;
} else if ( fileSize == 64 ) {
byte[] hex = new byte[64];
- bis.mark(64);
- if ( bis.read(hex, 0, 64) != 64 ) {
- throw new IOException("Error reading key.");
- }
-
try {
- return hexStringToByteArray(new String(hex));
+ return hexStringToByteArray(new String(keyData));
} catch (IndexOutOfBoundsException e) {
// Key is not base 64, treat it as binary data
- bis.reset();
}
}
@@ -190,14 +172,7 @@ public abstract class PwDatabase {
int offset = 0;
try {
- while (true) {
- int bytesRead = bis.read(buffer, 0, 2048);
- if ( bytesRead == -1 ) break; // End of file
-
- md.update(buffer, 0, bytesRead);
- offset += bytesRead;
-
- }
+ md.update(keyData);
} catch (Exception e) {
System.out.println(e.toString());
}
@@ -205,7 +180,7 @@ public abstract class PwDatabase {
return md.digest();
}
- protected abstract byte[] loadXmlKeyFile(String fileName);
+ protected abstract byte[] loadXmlKeyFile(InputStream keyInputStream);
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
diff --git a/app/src/main/java/com/keepassdroid/database/PwDatabaseV3.java b/app/src/main/java/com/keepassdroid/database/PwDatabaseV3.java
index 93b110b43..b06c8c5c5 100644
--- a/app/src/main/java/com/keepassdroid/database/PwDatabaseV3.java
+++ b/app/src/main/java/com/keepassdroid/database/PwDatabaseV3.java
@@ -47,6 +47,7 @@ package com.keepassdroid.database;
// Java
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@@ -219,16 +220,16 @@ public class PwDatabaseV3 extends PwDatabase {
return newId;
}
- public byte[] getMasterKey(String key, String keyFileName)
+ public byte[] getMasterKey(String key, InputStream keyInputStream)
throws InvalidKeyFileException, IOException {
- assert (key != null && keyFileName != null);
+ assert (key != null);
- if (key.length() > 0 && keyFileName.length() > 0) {
- return getCompositeKey(key, keyFileName);
+ if (key.length() > 0 && keyInputStream != null) {
+ return getCompositeKey(key, keyInputStream);
} else if (key.length() > 0) {
return getPasswordKey(key);
- } else if (keyFileName.length() > 0) {
- return getFileKey(keyFileName);
+ } else if (keyInputStream != null) {
+ return getFileKey(keyInputStream);
} else {
throw new IllegalArgumentException("Key cannot be empty.");
}
@@ -241,7 +242,7 @@ public class PwDatabaseV3 extends PwDatabase {
}
@Override
- protected byte[] loadXmlKeyFile(String fileName) {
+ protected byte[] loadXmlKeyFile(InputStream keyInputStream) {
return null;
}
diff --git a/app/src/main/java/com/keepassdroid/database/PwDatabaseV4.java b/app/src/main/java/com/keepassdroid/database/PwDatabaseV4.java
index 16856a10b..353eb9954 100644
--- a/app/src/main/java/com/keepassdroid/database/PwDatabaseV4.java
+++ b/app/src/main/java/com/keepassdroid/database/PwDatabaseV4.java
@@ -21,6 +21,7 @@ package com.keepassdroid.database;
import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
@@ -107,18 +108,18 @@ public class PwDatabaseV4 extends PwDatabase {
}
@Override
- public byte[] getMasterKey(String key, String keyFileName)
+ public byte[] getMasterKey(String key, InputStream keyInputStream)
throws InvalidKeyFileException, IOException {
- assert( key != null && keyFileName != null );
+ assert(key != null);
byte[] fKey;
- if ( key.length() > 0 && keyFileName.length() > 0 ) {
- return getCompositeKey(key, keyFileName);
+ if ( key.length() > 0 && keyInputStream != null) {
+ return getCompositeKey(key, keyInputStream);
} else if ( key.length() > 0 ) {
fKey = getPasswordKey(key);
- } else if ( keyFileName.length() > 0 ) {
- fKey = getFileKey(keyFileName);
+ } else if ( keyInputStream != null) {
+ fKey = getFileKey(keyInputStream);
} else {
throw new IllegalArgumentException( "Key cannot be empty." );
}
@@ -145,12 +146,11 @@ public class PwDatabaseV4 extends PwDatabase {
private static final String KeyDataElementName = "Data";
@Override
- protected byte[] loadXmlKeyFile(String fileName) {
+ protected byte[] loadXmlKeyFile(InputStream keyInputStream) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
- FileInputStream fis = new FileInputStream(fileName);
- Document doc = db.parse(fis);
+ Document doc = db.parse(keyInputStream);
Element el = doc.getDocumentElement();
if (el == null || ! el.getNodeName().equalsIgnoreCase(RootElementName)) {
diff --git a/app/src/main/java/com/keepassdroid/database/edit/CreateDB.java b/app/src/main/java/com/keepassdroid/database/edit/CreateDB.java
index 6888e945a..984f7a914 100644
--- a/app/src/main/java/com/keepassdroid/database/edit/CreateDB.java
+++ b/app/src/main/java/com/keepassdroid/database/edit/CreateDB.java
@@ -28,6 +28,7 @@ import com.keepassdroid.app.App;
import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.PwDatabaseV3;
import com.keepassdroid.database.PwEncryptionAlgorithm;
+import com.keepassdroid.utils.UriUtil;
public class CreateDB extends RunnableOnFinish {
@@ -57,7 +58,7 @@ public class CreateDB extends RunnableOnFinish {
// Set Database state
db.pm = pm;
Uri.Builder b = new Uri.Builder();
- db.mUri = b.scheme("path").path(mFilename).build();
+ db.mUri = UriUtil.parseDefaultFile(mFilename);
db.setLoaded();
// Commit changes
diff --git a/app/src/main/java/com/keepassdroid/database/edit/FileOnFinish.java b/app/src/main/java/com/keepassdroid/database/edit/FileOnFinish.java
index 2f00b2fea..c542caff4 100644
--- a/app/src/main/java/com/keepassdroid/database/edit/FileOnFinish.java
+++ b/app/src/main/java/com/keepassdroid/database/edit/FileOnFinish.java
@@ -1,7 +1,28 @@
+/*
+ * Copyright 2016 Brian Pellin.
+ *
+ * This file is part of KeePassDroid.
+ *
+ * KeePassDroid is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * KeePassDroid is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KeePassDroid. If not, see .
+ *
+ */
package com.keepassdroid.database.edit;
+import android.net.Uri;
+
public class FileOnFinish extends OnFinish {
- private String mFilename = "";
+ private Uri mFilename = null;
protected FileOnFinish mOnFinish;
public FileOnFinish(FileOnFinish finish) {
@@ -10,11 +31,11 @@ public class FileOnFinish extends OnFinish {
mOnFinish = finish;
}
- public void setFilename(String filename) {
+ public void setFilename(Uri filename) {
mFilename = filename;
}
- public String getFilename() {
+ public Uri getFilename() {
return mFilename;
}
diff --git a/app/src/main/java/com/keepassdroid/database/edit/LoadDB.java b/app/src/main/java/com/keepassdroid/database/edit/LoadDB.java
index eac25e096..7afabc8ef 100644
--- a/app/src/main/java/com/keepassdroid/database/edit/LoadDB.java
+++ b/app/src/main/java/com/keepassdroid/database/edit/LoadDB.java
@@ -42,12 +42,12 @@ import com.keepassdroid.database.exception.KeyFileEmptyException;
public class LoadDB extends RunnableOnFinish {
private Uri mUri;
private String mPass;
- private String mKey;
+ private Uri mKey;
private Database mDb;
private Context mCtx;
private boolean mRememberKeyfile;
- public LoadDB(Database db, Context ctx, Uri uri, String pass, String key, OnFinish finish) {
+ public LoadDB(Database db, Context ctx, Uri uri, String pass, Uri key, OnFinish finish) {
super(finish);
mDb = db;
@@ -105,9 +105,9 @@ public class LoadDB extends RunnableOnFinish {
finish(true);
}
- private void saveFileData(Uri uri, String key) {
+ private void saveFileData(Uri uri, Uri key) {
if ( ! mRememberKeyfile ) {
- key = "";
+ key = null;
}
App.getFileHistory().createFile(uri, key);
diff --git a/app/src/main/java/com/keepassdroid/database/edit/SetPassword.java b/app/src/main/java/com/keepassdroid/database/edit/SetPassword.java
index a904165ee..09aa46bcf 100644
--- a/app/src/main/java/com/keepassdroid/database/edit/SetPassword.java
+++ b/app/src/main/java/com/keepassdroid/database/edit/SetPassword.java
@@ -20,29 +20,32 @@
package com.keepassdroid.database.edit;
import java.io.IOException;
+import java.io.InputStream;
import android.content.Context;
import android.content.DialogInterface;
+import android.net.Uri;
import com.keepassdroid.Database;
import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.exception.InvalidKeyFileException;
import com.keepassdroid.dialog.PasswordEncodingDialogHelper;
+import com.keepassdroid.utils.UriUtil;
public class SetPassword extends RunnableOnFinish {
private String mPassword;
- private String mKeyfile;
+ private Uri mKeyfile;
private Database mDb;
private boolean mDontSave;
private Context ctx;
- public SetPassword(Context ctx, Database db, String password, String keyfile, OnFinish finish) {
+ public SetPassword(Context ctx, Database db, String password, Uri keyfile, OnFinish finish) {
this(ctx, db, password, keyfile, finish, false);
}
- public SetPassword(Context ctx, Database db, String password, String keyfile, OnFinish finish, boolean dontSave) {
+ public SetPassword(Context ctx, Database db, String password, Uri keyfile, OnFinish finish, boolean dontSave) {
super(finish);
mDb = db;
@@ -71,7 +74,8 @@ public class SetPassword extends RunnableOnFinish {
// Set key
try {
- pm.setMasterKey(mPassword, mKeyfile);
+ InputStream is = UriUtil.getUriInputStream(ctx, mKeyfile);
+ pm.setMasterKey(mPassword, is);
} catch (InvalidKeyFileException e) {
erase(backupKey);
finish(false, e.getMessage());
diff --git a/app/src/main/java/com/keepassdroid/database/load/Importer.java b/app/src/main/java/com/keepassdroid/database/load/Importer.java
index fce4a176d..da0797ef1 100644
--- a/app/src/main/java/com/keepassdroid/database/load/Importer.java
+++ b/app/src/main/java/com/keepassdroid/database/load/Importer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Brian Pellin.
+ * Copyright 2009-2016 Brian Pellin.
*
* This file is part of KeePassDroid.
*
@@ -30,10 +30,10 @@ public abstract class Importer {
public static final boolean DEBUG = true;
- public abstract PwDatabase openDatabase( InputStream inStream, String password, String keyfile )
+ public abstract PwDatabase openDatabase( InputStream inStream, String password, InputStream keyInputStream)
throws IOException, InvalidDBException;
- public abstract PwDatabase openDatabase( InputStream inStream, String password, String keyfile, UpdateStatus status )
+ public abstract PwDatabase openDatabase( InputStream inStream, String password, InputStream keyInputStream, UpdateStatus status )
throws IOException, InvalidDBException;
diff --git a/app/src/main/java/com/keepassdroid/database/load/ImporterV3.java b/app/src/main/java/com/keepassdroid/database/load/ImporterV3.java
index 8f1a72db6..e0bc82788 100644
--- a/app/src/main/java/com/keepassdroid/database/load/ImporterV3.java
+++ b/app/src/main/java/com/keepassdroid/database/load/ImporterV3.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2012 Brian Pellin.
+ * Copyright 2009-2016 Brian Pellin.
*
* This file is part of KeePassDroid.
*
@@ -105,9 +105,8 @@ public class ImporterV3 extends Importer {
/**
* Load a v3 database file, return contents in a new PwDatabaseV3.
*
- * @param infile Existing file to load.
+ * @param inStream Existing file to load.
* @param password Pass phrase for infile.
- * @param pRepair (unused)
* @return new PwDatabaseV3 container.
*
* @throws IOException on any file error.
@@ -123,13 +122,13 @@ public class ImporterV3 extends Importer {
* @throws InvalidAlgorithmParameterException if error decrypting main file body.
* @throws ShortBufferException if error decrypting main file body.
*/
- public PwDatabaseV3 openDatabase( InputStream inStream, String password, String keyfile )
+ public PwDatabaseV3 openDatabase( InputStream inStream, String password, InputStream kfIs)
throws IOException, InvalidDBException
{
- return openDatabase(inStream, password, keyfile, new UpdateStatus());
+ return openDatabase(inStream, password, kfIs, new UpdateStatus());
}
- public PwDatabaseV3 openDatabase( InputStream inStream, String password, String keyfile, UpdateStatus status )
+ public PwDatabaseV3 openDatabase( InputStream inStream, String password, InputStream kfIs, UpdateStatus status )
throws IOException, InvalidDBException
{
PwDatabaseV3 newManager;
@@ -157,7 +156,7 @@ public class ImporterV3 extends Importer {
status.updateMessage(R.string.creating_db_key);
newManager = createDB();
- newManager.setMasterKey( password, keyfile );
+ newManager.setMasterKey(password, kfIs);
// Select algorithm
if( (hdr.flags & PwDbHeaderV3.FLAG_RIJNDAEL) != 0 ) {
diff --git a/app/src/main/java/com/keepassdroid/database/load/ImporterV3Debug.java b/app/src/main/java/com/keepassdroid/database/load/ImporterV3Debug.java
index 2e019de72..09f41485d 100644
--- a/app/src/main/java/com/keepassdroid/database/load/ImporterV3Debug.java
+++ b/app/src/main/java/com/keepassdroid/database/load/ImporterV3Debug.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Brian Pellin.
+ * Copyright 2011-2016 Brian Pellin.
*
* This file is part of KeePassDroid.
*
@@ -35,9 +35,9 @@ public class ImporterV3Debug extends ImporterV3 {
@Override
public PwDatabaseV3Debug openDatabase(InputStream inStream, String password,
- String keyfile, UpdateStatus status) throws IOException,
+ InputStream keyInputStream, UpdateStatus status) throws IOException,
InvalidDBException {
- return (PwDatabaseV3Debug) super.openDatabase(inStream, password, keyfile, status);
+ return (PwDatabaseV3Debug) super.openDatabase(inStream, password, keyInputStream, status);
}
diff --git a/app/src/main/java/com/keepassdroid/database/load/ImporterV4.java b/app/src/main/java/com/keepassdroid/database/load/ImporterV4.java
index 94284b80a..8775cf156 100644
--- a/app/src/main/java/com/keepassdroid/database/load/ImporterV4.java
+++ b/app/src/main/java/com/keepassdroid/database/load/ImporterV4.java
@@ -84,14 +84,14 @@ public class ImporterV4 extends Importer {
@Override
public PwDatabaseV4 openDatabase(InputStream inStream, String password,
- String keyfile) throws IOException, InvalidDBException {
+ InputStream keyInputStream) throws IOException, InvalidDBException {
- return openDatabase(inStream, password, keyfile, new UpdateStatus());
+ return openDatabase(inStream, password, keyInputStream, new UpdateStatus());
}
@Override
public PwDatabaseV4 openDatabase(InputStream inStream, String password,
- String keyfile, UpdateStatus status) throws IOException,
+ InputStream keyInputStream, UpdateStatus status) throws IOException,
InvalidDBException {
db = createDB();
@@ -100,7 +100,7 @@ public class ImporterV4 extends Importer {
hashOfHeader = header.loadFromFile(inStream);
- db.setMasterKey(password, keyfile);
+ db.setMasterKey(password, keyInputStream);
db.makeFinalKey(header.masterSeed, header.transformSeed, (int)db.numKeyEncRounds);
// Attach decryptor
diff --git a/app/src/main/java/com/keepassdroid/database/load/ImporterV4Debug.java b/app/src/main/java/com/keepassdroid/database/load/ImporterV4Debug.java
index 5cc35b14d..9943d60fd 100644
--- a/app/src/main/java/com/keepassdroid/database/load/ImporterV4Debug.java
+++ b/app/src/main/java/com/keepassdroid/database/load/ImporterV4Debug.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Brian Pellin.
+ * Copyright 2011-2016 Brian Pellin.
*
* This file is part of KeePassDroid.
*
@@ -35,9 +35,9 @@ public class ImporterV4Debug extends ImporterV4 {
@Override
public PwDatabaseV4Debug openDatabase(InputStream inStream, String password,
- String keyfile, UpdateStatus status) throws IOException,
+ InputStream keyInputFile, UpdateStatus status) throws IOException,
InvalidDBException {
- return (PwDatabaseV4Debug) super.openDatabase(inStream, password, keyfile, status);
+ return (PwDatabaseV4Debug) super.openDatabase(inStream, password, keyInputFile, status);
}
}
diff --git a/app/src/main/java/com/keepassdroid/fileselect/RecentFileHistory.java b/app/src/main/java/com/keepassdroid/fileselect/RecentFileHistory.java
index 3b20729c3..29267e2f7 100644
--- a/app/src/main/java/com/keepassdroid/fileselect/RecentFileHistory.java
+++ b/app/src/main/java/com/keepassdroid/fileselect/RecentFileHistory.java
@@ -25,6 +25,7 @@ import java.util.List;
import com.android.keepass.R;
import com.keepassdroid.compat.EditorCompat;
+import com.keepassdroid.utils.UriUtil;
import android.content.Context;
import android.content.SharedPreferences;
@@ -125,8 +126,8 @@ public class RecentFileHistory {
return db.exists();
}
- public void createFile(Uri uri, String keyFile) {
- if (!enabled) return;
+ public void createFile(Uri uri, Uri keyUri) {
+ if (!enabled || uri == null || keyUri == null) return;
init();
@@ -134,7 +135,7 @@ public class RecentFileHistory {
deleteFile(uri, false);
databases.add(0, uri.toString());
- keyfiles.add(0, keyFile);
+ keyfiles.add(0, keyUri.toString());
trimLists();
savePrefs();
@@ -220,19 +221,19 @@ public class RecentFileHistory {
return databases;
}
- public String getFileByName(String database) {
- if (!enabled) return "";
+ public Uri getFileByName(Uri database) {
+ if (!enabled) return null;
init();
int size = databases.size();
for (int i = 0; i < size; i++) {
- if (database.equals(databases.get(i))) {
- return keyfiles.get(i);
+ if (UriUtil.equalsDefaultfile(database,databases.get(i))) {
+ return UriUtil.parseDefaultFile(keyfiles.get(i));
}
}
- return "";
+ return null;
}
public void deleteAll() {
diff --git a/app/src/main/java/com/keepassdroid/utils/EmptyUtils.java b/app/src/main/java/com/keepassdroid/utils/EmptyUtils.java
index 544d2065a..3b3d250dd 100644
--- a/app/src/main/java/com/keepassdroid/utils/EmptyUtils.java
+++ b/app/src/main/java/com/keepassdroid/utils/EmptyUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Brian Pellin.
+ * Copyright 2012-2016 Brian Pellin.
*
* This file is part of KeePassDroid.
*
@@ -19,6 +19,8 @@
*/
package com.keepassdroid.utils;
+import android.net.Uri;
+
import com.keepassdroid.database.PwDate;
import com.keepassdroid.database.PwEntryV3;
@@ -34,4 +36,8 @@ public class EmptyUtils {
public static boolean isNullOrEmpty(PwDate date) {
return (date == null) || date.equals(PwEntryV3.DEFAULT_PWDATE);
}
+
+ public static boolean isNullOrEmpty(Uri uri) {
+ return (uri==null) || (uri.toString().length() == 0);
+ }
}
diff --git a/app/src/main/java/com/keepassdroid/utils/UriUtil.java b/app/src/main/java/com/keepassdroid/utils/UriUtil.java
new file mode 100644
index 000000000..becbad19c
--- /dev/null
+++ b/app/src/main/java/com/keepassdroid/utils/UriUtil.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2016 Brian Pellin.
+ *
+ * This file is part of KeePassDroid.
+ *
+ * KeePassDroid is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * KeePassDroid is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KeePassDroid. If not, see .
+ *
+ */
+package com.keepassdroid.utils;
+
+import android.content.Context;
+import android.net.Uri;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+/**
+ * Created by bpellin on 3/5/16.
+ */
+public class UriUtil {
+ public static Uri parseDefaultFile(String text) {
+ if (EmptyUtils.isNullOrEmpty(text)) {
+ return null;
+ }
+
+ Uri uri = Uri.parse(text);
+ if (EmptyUtils.isNullOrEmpty(uri.getScheme())) {
+ uri = uri.buildUpon().scheme("file").authority("").build();
+ }
+
+ return uri;
+ }
+ public static Uri parseDefaultFile(Uri uri) {
+ if (EmptyUtils.isNullOrEmpty(uri.getScheme())) {
+ uri = uri.buildUpon().scheme("file").authority("").build();
+ }
+
+ return uri;
+ }
+
+ public static boolean equalsDefaultfile(Uri left, String right) {
+ left = parseDefaultFile(left);
+ Uri uriRight = parseDefaultFile(right);
+
+ return left.equals(uriRight);
+ }
+
+ public static InputStream getUriInputStream(Context ctx, Uri uri) throws FileNotFoundException {
+ if (uri == null) return null;
+
+ String scheme = uri.getScheme();
+ if (scheme.equals("file")) {
+ return new FileInputStream(uri.getPath());
+ }
+ else if (scheme.equals("content")) {
+ return ctx.getContentResolver().openInputStream(uri);
+ }
+ else {
+ return null;
+ }
+ }
+}