mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Cleanup.
This commit is contained in:
@@ -82,12 +82,38 @@
|
||||
android:layout_alignLeft="@id/entry_title"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@id/entry_created_label"/>
|
||||
<!-- Modified -->
|
||||
<TextView android:id="@+id/entry_modified_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@id/entry_created_label"
|
||||
android:text="@string/entry_modified" />
|
||||
<TextView android:id="@+id/entry_modified"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@id/entry_title"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@id/entry_modified_label"/>
|
||||
<!-- Accessed -->
|
||||
<TextView android:id="@+id/entry_accessed_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@id/entry_modified_label"
|
||||
android:text="@string/entry_accessed" />
|
||||
<TextView android:id="@+id/entry_accessed"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@id/entry_title"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@id/entry_accessed_label"/>
|
||||
<!-- Comment -->
|
||||
<TextView android:id="@+id/entry_comment_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@id/entry_created"
|
||||
android:layout_below="@id/entry_accessed"
|
||||
android:text="@string/entry_comment" />
|
||||
<TextView android:id="@+id/entry_comment"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -39,4 +39,6 @@
|
||||
<string name="about_twitter">Twitter:</string>
|
||||
<string name="about_ok">OK</string>
|
||||
<string name="entry_created">Created: </string>
|
||||
<string name="entry_modified">Modified: </string>
|
||||
<string name="entry_accessed">Accessed: </string>
|
||||
</resources>
|
||||
|
||||
@@ -19,8 +19,10 @@
|
||||
*/
|
||||
package com.android.keepass;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
@@ -34,12 +36,15 @@ import org.phoneid.keepassj2me.PwGroup;
|
||||
import org.phoneid.keepassj2me.PwManager;
|
||||
|
||||
import com.android.keepass.keepasslib.InvalidKeyFileException;
|
||||
import com.android.keepass.keepasslib.PwManagerOutput;
|
||||
import com.android.keepass.keepasslib.PwManagerOutput.PwManagerOutputException;
|
||||
|
||||
public class Database {
|
||||
public static HashMap<Integer, WeakReference<PwGroup>> gGroups = new HashMap<Integer, WeakReference<PwGroup>>();
|
||||
public static HashMap<UUID, WeakReference<PwEntry>> gEntries = new HashMap<UUID, WeakReference<PwEntry>>();
|
||||
public static PwGroup gRoot;
|
||||
public static PwManager mPM;
|
||||
public static String mFilename;
|
||||
|
||||
public static void LoadData(String filename, String password, String keyfile) throws InvalidCipherTextException, IOException, InvalidKeyFileException, FileNotFoundException {
|
||||
FileInputStream fis;
|
||||
@@ -52,6 +57,30 @@ public class Database {
|
||||
mPM.constructTree(null);
|
||||
populateGlobals(null);
|
||||
}
|
||||
|
||||
mFilename = filename;
|
||||
}
|
||||
|
||||
public static void SaveData() throws IOException, PwManagerOutputException {
|
||||
SaveData(mFilename);
|
||||
}
|
||||
|
||||
public static void SaveData(String filename) throws IOException, PwManagerOutputException {
|
||||
File tempFile = new File(filename + ".tmp");
|
||||
FileOutputStream fos = new FileOutputStream(tempFile);
|
||||
PwManagerOutput pmo = new PwManagerOutput(mPM, fos);
|
||||
pmo.output();
|
||||
fos.close();
|
||||
|
||||
File orig = new File(filename);
|
||||
orig.delete();
|
||||
|
||||
if ( ! tempFile.renameTo(orig) ) {
|
||||
throw new IOException("Failed to store database.");
|
||||
}
|
||||
|
||||
mFilename = filename;
|
||||
|
||||
}
|
||||
|
||||
private static void populateGlobals(PwGroup currentGroup) {
|
||||
@@ -87,6 +116,7 @@ public class Database {
|
||||
gEntries.clear();
|
||||
gRoot = null;
|
||||
mPM = null;
|
||||
mFilename = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
package com.android.keepass;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
@@ -36,7 +37,6 @@ import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class EntryActivity extends LockingActivity {
|
||||
public static final String KEY_ENTRY = "entry";
|
||||
@@ -72,6 +72,10 @@ public class EntryActivity extends LockingActivity {
|
||||
assert(uuid != null);
|
||||
|
||||
mEntry = Database.gEntries.get(uuid).get();
|
||||
|
||||
// Update last access time.
|
||||
Calendar cal = Calendar.getInstance();
|
||||
mEntry.tLastAccess = cal.getTime();
|
||||
|
||||
fillData();
|
||||
}
|
||||
@@ -83,8 +87,9 @@ public class EntryActivity extends LockingActivity {
|
||||
populateText(R.id.entry_password, getString(R.string.MaskedPassword));
|
||||
|
||||
DateFormat df = DateFormat.getInstance();
|
||||
String date = df.format(mEntry.tCreation);
|
||||
populateText(R.id.entry_created, date);
|
||||
populateText(R.id.entry_created, df.format(mEntry.tCreation));
|
||||
populateText(R.id.entry_modified, df.format(mEntry.tLastMod));
|
||||
populateText(R.id.entry_accessed, df.format(mEntry.tLastAccess));
|
||||
populateText(R.id.entry_comment, mEntry.additional);
|
||||
TextView comment = (TextView)findViewById(R.id.entry_comment);
|
||||
comment.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
|
||||
|
||||
@@ -237,22 +237,6 @@ public class PasswordActivity extends Activity {
|
||||
public void run() {
|
||||
mPd.dismiss();
|
||||
|
||||
// TODO: Remove the below block
|
||||
ByteArrayOutputStream bActual = new ByteArrayOutputStream();
|
||||
PwManagerOutput pActual = new PwManagerOutput(Database.mPM, bActual, PwManagerOutput.DEBUG);
|
||||
try {
|
||||
pActual.output();
|
||||
} catch (PwManagerOutputException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
// TODO: End block
|
||||
|
||||
if ( mMsg.length() > 0 ) {
|
||||
Toast.makeText(PasswordActivity.this, mMsg, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@@ -79,47 +79,6 @@ public class PwManagerOutput {
|
||||
|
||||
byte[] finalKey = getFinalKey(header);
|
||||
|
||||
/*
|
||||
// Bouncy Castle implementation
|
||||
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()), new PKCS7Padding());
|
||||
cipher.init(true, new ParametersWithIV(new KeyParameter(finalKey), header.encryptionIV));
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
outputPlanGroupAndEntries(bos);
|
||||
bos.close();
|
||||
|
||||
byte[] output = bos.toByteArray();
|
||||
byte[] encrypted = new byte[cipher.getOutputSize(output.length)];
|
||||
int bytes = cipher.processBytes(output, 0, output.length, encrypted, 0);
|
||||
try {
|
||||
bytes += cipher.doFinal(encrypted, bytes);
|
||||
} catch (DataLengthException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IllegalStateException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (InvalidCipherTextException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
mOS.write(encrypted, 0, bytes);
|
||||
*/
|
||||
|
||||
/*
|
||||
BufferedBlockCipherOutputStream bbcos = new BufferedBlockCipherOutputStream(mOS, cipher);
|
||||
outputPlanGroupAndEntries(bbcos);
|
||||
bbcos.close();
|
||||
*/
|
||||
/*
|
||||
try {
|
||||
bbcos.close();
|
||||
} catch (IOException e) {
|
||||
throw new PwManagerOutputException("Failed to close encryption stream.");
|
||||
}
|
||||
*/
|
||||
|
||||
Cipher cipher;
|
||||
try {
|
||||
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
@@ -139,7 +98,6 @@ public class PwManagerOutput {
|
||||
} catch (IOException e) {
|
||||
throw new PwManagerOutputException("Failed to output final encrypted part.");
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
public PwDbHeader outputHeader(OutputStream os) throws PwManagerOutputException {
|
||||
@@ -185,7 +143,6 @@ public class PwManagerOutput {
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
assert true;
|
||||
throw new PwManagerOutputException("SHA-256 not implemented here.");
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@ import android.util.Log;
|
||||
|
||||
import com.android.keepass.keepasslib.InvalidKeyFileException;
|
||||
import com.android.keepass.keepasslib.NullOutputStream;
|
||||
import com.android.keepass.keepasslib.PwManagerOutput.PwManagerOutputException;
|
||||
|
||||
/**
|
||||
* Load a v3 database file.
|
||||
@@ -336,12 +335,13 @@ public class ImporterV3 {
|
||||
|
||||
/**
|
||||
* Encrypt the master key a few times to make brute-force key-search harder
|
||||
* @throws IOException
|
||||
* @throws NoSuchPaddingException
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws ShortBufferException
|
||||
*/
|
||||
|
||||
public static byte[] transformMasterKey( byte[] pKeySeed, byte[] pKey, int rounds )
|
||||
public static byte[] transformMasterKey( byte[] pKeySeed, byte[] pKey, int rounds ) throws IOException
|
||||
/*throws InvalidKeyException,
|
||||
IllegalBlockSizeException,
|
||||
BadPaddingException,
|
||||
@@ -350,6 +350,7 @@ public class ImporterV3 {
|
||||
//KeePassMIDlet.logS("transformMasterKey, rounds=" + rounds);
|
||||
//KeePassMIDlet.logS("transformMasterKey, pkey=" + new String(Hex.encode(pKey)));
|
||||
|
||||
// Bouncy castle implementation
|
||||
byte[] newKey = new byte[pKey.length];
|
||||
int i;
|
||||
|
||||
@@ -361,6 +362,7 @@ public class ImporterV3 {
|
||||
for( i = 0; i < rounds; i++ )
|
||||
cipher.processBytes (newKey, 0, newKey.length, newKey, 0);
|
||||
|
||||
/*
|
||||
// Hash once with SHA-256
|
||||
SHA256Digest md = new SHA256Digest();
|
||||
md.update(newKey, 0, newKey.length );
|
||||
@@ -368,6 +370,50 @@ public class ImporterV3 {
|
||||
md.doFinal(newKey, 0);
|
||||
|
||||
return newKey;
|
||||
*/
|
||||
|
||||
/* Native implementation is not quite right yet
|
||||
byte[] newKey = new byte[pKey.length];
|
||||
Cipher cipher;
|
||||
try {
|
||||
cipher = Cipher.getInstance("AES");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IOException("NoSuchAlgorithm: " + e.getMessage());
|
||||
} catch (NoSuchPaddingException e) {
|
||||
throw new IOException("NoSuchPadding: " + e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(pKeySeed, "AES"));
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new IOException("InvalidKeyException: " + e.getMessage());
|
||||
}
|
||||
|
||||
// Encrypt key rounds times
|
||||
System.arraycopy(pKey, 0, newKey, 0, pKey.length);
|
||||
for (int i = 0; i < rounds; i++) {
|
||||
try {
|
||||
cipher.update(newKey, 0, newKey.length, newKey, 0);
|
||||
|
||||
} catch (ShortBufferException e) {
|
||||
throw new IOException("Short buffer: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Hash the key
|
||||
MessageDigest md = null;
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
assert true;
|
||||
throw new IOException("SHA-256 not implemented here: " + e.getMessage());
|
||||
}
|
||||
|
||||
md.update(newKey);
|
||||
return md.digest();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
16
tests/src/com/android/keepass/tests/DatabaseTest.java
Normal file
16
tests/src/com/android/keepass/tests/DatabaseTest.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package com.android.keepass.tests;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.android.keepass.Database;
|
||||
|
||||
public class DatabaseTest extends TestCase {
|
||||
public void testDatabase() {
|
||||
try {
|
||||
Database.LoadData("/sdcard/test1.kdb", "12345", "");
|
||||
Database.SaveData("/sdcard/test2.kdb");
|
||||
} catch (Exception e) {
|
||||
assertTrue(e.getMessage(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,5 +142,5 @@ public class PwManagerOutputTest extends TestCase {
|
||||
assertArrayEquals("Databases do not match.", bExpected.toByteArray(), bActual.toByteArray());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -20,7 +20,6 @@
|
||||
package com.android.keepass.tests;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bouncycastle.crypto.InvalidCipherTextException;
|
||||
|
||||
Reference in New Issue
Block a user