This commit is contained in:
Brian Pellin
2009-05-04 21:21:49 -05:00
parent af7dab779a
commit ad70b61378
10 changed files with 132 additions and 67 deletions

View File

@@ -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"

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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.");
}

View File

@@ -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();
}

View 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);
}
}
}

View File

@@ -142,5 +142,5 @@ public class PwManagerOutputTest extends TestCase {
assertArrayEquals("Databases do not match.", bExpected.toByteArray(), bActual.toByteArray());
}
}

View File

@@ -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;