mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Initial support for serializing groups and entries. Not quite right yet.
This commit is contained in:
12
build.xml
12
build.xml
@@ -297,7 +297,17 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="tests" depends="reinstall">
|
||||
<!-- Copy testing files to device -->
|
||||
<target name="stage">
|
||||
<echo>Copying test files..</echo>
|
||||
<exec executable="${adb}">
|
||||
<arg value="push" />
|
||||
<arg value="tests/assets/test1.kdb" />
|
||||
<arg value="/sdcard/test1.kdb" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="tests" depends="reinstall, stage">
|
||||
<echo>Building and installing tests..</echo>
|
||||
<exec executable="ant" failonerror="true">
|
||||
<arg value="-f" />
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
<!-- Title -->
|
||||
<TextView android:id="@+id/entry_title_label"
|
||||
android:layout_width="100px"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -30,6 +30,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_toRightOf="@id/entry_title_label"/>
|
||||
<!-- Username -->
|
||||
<TextView android:id="@+id/entry_user_name_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -42,6 +43,7 @@
|
||||
android:layout_alignLeft="@id/entry_title"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@id/entry_user_name_label"/>
|
||||
<!-- URL -->
|
||||
<TextView android:id="@+id/entry_url_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -54,6 +56,7 @@
|
||||
android:layout_alignLeft="@id/entry_title"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@id/entry_url_label"/>
|
||||
<!-- Password -->
|
||||
<TextView android:id="@+id/entry_password_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -66,11 +69,25 @@
|
||||
android:layout_alignLeft="@id/entry_title"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@id/entry_password_label"/>
|
||||
<!-- Created -->
|
||||
<TextView android:id="@+id/entry_created_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@id/entry_password_label"
|
||||
android:text="@string/entry_created" />
|
||||
<TextView android:id="@+id/entry_created"
|
||||
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_created_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_password"
|
||||
android:layout_below="@id/entry_created"
|
||||
android:text="@string/entry_comment" />
|
||||
<TextView android:id="@+id/entry_comment"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -38,4 +38,5 @@
|
||||
<string name="about_homepage">Homepage:</string>
|
||||
<string name="about_twitter">Twitter:</string>
|
||||
<string name="about_ok">OK</string>
|
||||
<string name="entry_created">Created: </string>
|
||||
</resources>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
package com.android.keepass;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
@@ -80,6 +81,10 @@ public class EntryActivity extends LockingActivity {
|
||||
populateText(R.id.entry_user_name, mEntry.username);
|
||||
populateText(R.id.entry_url, mEntry.url);
|
||||
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_comment, mEntry.additional);
|
||||
TextView comment = (TextView)findViewById(R.id.entry_comment);
|
||||
comment.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.lang.ref.WeakReference;
|
||||
import org.phoneid.keepassj2me.PwEntry;
|
||||
import org.phoneid.keepassj2me.PwGroup;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Vector;
|
||||
import org.phoneid.keepassj2me.PwEntry;
|
||||
import org.phoneid.keepassj2me.PwGroup;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
11
src/com/android/keepass/keepasslib/Exporter.java
Normal file
11
src/com/android/keepass/keepasslib/Exporter.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package com.android.keepass.keepasslib;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.phoneid.keepassj2me.PwManager;
|
||||
|
||||
public class Exporter {
|
||||
public void saveDatabase(PwManager manager, OutputStream outStream) {
|
||||
|
||||
}
|
||||
}
|
||||
150
src/com/android/keepass/keepasslib/PwEntryOutput.java
Normal file
150
src/com/android/keepass/keepasslib/PwEntryOutput.java
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2009 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.android.keepass.keepasslib;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.phoneid.keepassj2me.PwEntry;
|
||||
import org.phoneid.keepassj2me.Types;
|
||||
|
||||
public class PwEntryOutput {
|
||||
private OutputStream mOS;
|
||||
private PwEntry mPE;
|
||||
|
||||
/** Output the PwGroup to the stream
|
||||
* @param pe
|
||||
* @param os
|
||||
*/
|
||||
public PwEntryOutput(PwEntry pe, OutputStream os) {
|
||||
mPE = pe;
|
||||
mOS = os;
|
||||
}
|
||||
|
||||
//NOTE: Need be to careful about using ints. The actual type written to file is a unsigned int
|
||||
public void output() throws IOException {
|
||||
// UUID
|
||||
mOS.write(UUID_FIELD_TYPE);
|
||||
mOS.write(UUID_FIELD_SIZE);
|
||||
mOS.write(mPE.uuid);
|
||||
|
||||
// Group ID
|
||||
mOS.write(GROUPID_FIELD_TYPE);
|
||||
mOS.write(LONG_FOUR);
|
||||
mOS.write(Types.writeInt(mPE.groupId));
|
||||
|
||||
// Image ID
|
||||
mOS.write(IMAGEID_FIELD_TYPE);
|
||||
mOS.write(LONG_FOUR);
|
||||
mOS.write(Types.writeInt(mPE.imageId));
|
||||
|
||||
// Title
|
||||
byte[] title = mPE.title.getBytes("UTF-8");
|
||||
mOS.write(TITLE_FIELD_TYPE);
|
||||
mOS.write(Types.writeInt(title.length));
|
||||
mOS.write(title);
|
||||
|
||||
// URL
|
||||
byte[] url = mPE.url.getBytes("UTF-8");
|
||||
mOS.write(URL_FIELD_TYPE);
|
||||
mOS.write(Types.writeInt(url.length));
|
||||
mOS.write(url);
|
||||
|
||||
// Username
|
||||
byte[] username = mPE.username.getBytes("UTF-8");
|
||||
mOS.write(USERNAME_FIELD_TYPE);
|
||||
mOS.write(Types.writeInt(username.length));
|
||||
mOS.write(username);
|
||||
|
||||
// Password
|
||||
byte[] password = mPE.getPassword();
|
||||
mOS.write(PASSWORD_FIELD_TYPE);
|
||||
mOS.write(Types.writeInt(password.length));
|
||||
mOS.write(password);
|
||||
|
||||
// Additional
|
||||
byte[] additional = mPE.additional.getBytes("UTF-8");
|
||||
mOS.write(ADDITIONAL_FIELD_TYPE);
|
||||
mOS.write(Types.writeInt(additional.length));
|
||||
mOS.write(additional);
|
||||
|
||||
// Create date
|
||||
mOS.write(CREATE_FIELD_TYPE);
|
||||
mOS.write(DATE_FIELD_SIZE);
|
||||
mOS.write(Types.writeTime(mPE.tCreation));
|
||||
|
||||
// Modification date
|
||||
mOS.write(MOD_FIELD_TYPE);
|
||||
mOS.write(DATE_FIELD_SIZE);
|
||||
mOS.write(Types.writeTime(mPE.tLastMod));
|
||||
|
||||
// Access date
|
||||
mOS.write(ACCESS_FIELD_TYPE);
|
||||
mOS.write(DATE_FIELD_SIZE);
|
||||
mOS.write(Types.writeTime(mPE.tLastAccess));
|
||||
|
||||
// Expiration date
|
||||
mOS.write(EXPIRE_FIELD_TYPE);
|
||||
mOS.write(DATE_FIELD_SIZE);
|
||||
mOS.write(Types.writeTime(mPE.tExpire));
|
||||
|
||||
// Binary desc
|
||||
byte[] binaryDesc = mPE.binaryDesc.getBytes("UTF-8");
|
||||
mOS.write(BINARY_DESC_FIELD_TYPE);
|
||||
mOS.write(Types.writeInt(binaryDesc.length));
|
||||
mOS.write(binaryDesc);
|
||||
|
||||
// Binary data
|
||||
byte[] data = mPE.getBinaryData();
|
||||
mOS.write(BINARY_DATA_FIELD_TYPE);
|
||||
mOS.write(Types.writeInt(data.length));
|
||||
mOS.write(data);
|
||||
|
||||
// End
|
||||
mOS.write(END_FIELD_TYPE);
|
||||
mOS.write(ZERO_FIELD_SIZE);
|
||||
}
|
||||
|
||||
public static final byte[] UUID_FIELD_TYPE = { 0x00, 0x01};
|
||||
public static final byte[] GROUPID_FIELD_TYPE = { 0x00, 0x02};
|
||||
public static final byte[] IMAGEID_FIELD_TYPE = { 0x00, 0x03};
|
||||
public static final byte[] TITLE_FIELD_TYPE = { 0x00, 0x04};
|
||||
public static final byte[] URL_FIELD_TYPE = { 0x00, 0x05};
|
||||
public static final byte[] USERNAME_FIELD_TYPE = { 0x00, 0x06};
|
||||
public static final byte[] PASSWORD_FIELD_TYPE = { 0x00, 0x07};
|
||||
public static final byte[] ADDITIONAL_FIELD_TYPE = { 0x00, 0x08};
|
||||
public static final byte[] CREATE_FIELD_TYPE = { 0x00, 0x09};
|
||||
public static final byte[] MOD_FIELD_TYPE = { 0x00, 0x0A};
|
||||
public static final byte[] ACCESS_FIELD_TYPE = { 0x00, 0x0B};
|
||||
public static final byte[] EXPIRE_FIELD_TYPE = { 0x00, 0x0C};
|
||||
public static final byte[] BINARY_DESC_FIELD_TYPE = { 0x00, 0x0D};
|
||||
public static final byte[] BINARY_DATA_FIELD_TYPE = { 0x00, 0x0E};
|
||||
public static final byte[] END_FIELD_TYPE = Types.writeUByte(0xFFFF);
|
||||
public static final byte[] LONG_FOUR = { 0x00, 0x00, 0x00, 0x04};
|
||||
public static final byte[] UUID_FIELD_SIZE = { 0x00, 0x00, 0x00, 0x10};
|
||||
public static final byte[] DATE_FIELD_SIZE = { 0x00, 0x00, 0x00, 0x05};
|
||||
public static final byte[] IMAGEID_FIELD_SIZE = LONG_FOUR;
|
||||
public static final byte[] LEVEL_FIELD_SIZE = LONG_FOUR;
|
||||
public static final byte[] FLAGS_FIELD_SIZE = LONG_FOUR;
|
||||
public static final byte[] ZERO_FIELD_SIZE = { 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
|
||||
|
||||
}
|
||||
112
src/com/android/keepass/keepasslib/PwGroupOutput.java
Normal file
112
src/com/android/keepass/keepasslib/PwGroupOutput.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2009 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.android.keepass.keepasslib;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.phoneid.keepassj2me.PwGroup;
|
||||
import org.phoneid.keepassj2me.Types;
|
||||
|
||||
public class PwGroupOutput {
|
||||
private OutputStream mOS;
|
||||
private PwGroup mPG;
|
||||
|
||||
/** Output the PwGroup to the stream
|
||||
* @param pg
|
||||
* @param os
|
||||
*/
|
||||
public PwGroupOutput(PwGroup pg, OutputStream os) {
|
||||
mPG = pg;
|
||||
mOS = os;
|
||||
}
|
||||
|
||||
//NOTE: Need be to careful about using ints. The actual type written to file is a unsigned int
|
||||
public void output() throws IOException {
|
||||
// Group ID
|
||||
mOS.write(GROUPID_FIELD_TYPE);
|
||||
mOS.write(GROUPID_FIELD_SIZE);
|
||||
mOS.write(Types.writeInt(mPG.groupId));
|
||||
|
||||
// Name
|
||||
mOS.write(NAME_FIELD_TYPE);
|
||||
mOS.write(Types.writeInt(mPG.name.length()));
|
||||
mOS.write(mPG.name.getBytes("UTF-8"));
|
||||
|
||||
// Create date
|
||||
mOS.write(CREATE_FIELD_TYPE);
|
||||
mOS.write(DATE_FIELD_SIZE);
|
||||
mOS.write(Types.writeTime(mPG.tCreation));
|
||||
|
||||
// Modification date
|
||||
mOS.write(MOD_FIELD_TYPE);
|
||||
mOS.write(DATE_FIELD_SIZE);
|
||||
mOS.write(Types.writeTime(mPG.tLastMod));
|
||||
|
||||
// Access date
|
||||
mOS.write(ACCESS_FIELD_TYPE);
|
||||
mOS.write(DATE_FIELD_SIZE);
|
||||
mOS.write(Types.writeTime(mPG.tLastAccess));
|
||||
|
||||
// Expiration date
|
||||
mOS.write(EXPIRE_FIELD_TYPE);
|
||||
mOS.write(DATE_FIELD_SIZE);
|
||||
mOS.write(Types.writeTime(mPG.tExpire));
|
||||
|
||||
// Image ID
|
||||
mOS.write(IMAGEID_FIELD_TYPE);
|
||||
mOS.write(IMAGEID_FIELD_SIZE);
|
||||
mOS.write(Types.writeInt(mPG.imageId));
|
||||
|
||||
// Level
|
||||
mOS.write(LEVEL_FIELD_TYPE);
|
||||
mOS.write(LEVEL_FIELD_SIZE);
|
||||
mOS.write(Types.writeShort(mPG.level));
|
||||
|
||||
// Flags
|
||||
mOS.write(FLAGS_FIELD_TYPE);
|
||||
mOS.write(FLAGS_FIELD_SIZE);
|
||||
mOS.write(Types.writeInt(mPG.flags));
|
||||
|
||||
// End
|
||||
mOS.write(END_FIELD_TYPE);
|
||||
mOS.write(ZERO_FIELD_SIZE);
|
||||
}
|
||||
|
||||
public static final byte[] GROUPID_FIELD_TYPE = { 0x00, 0x01};
|
||||
public static final byte[] NAME_FIELD_TYPE = { 0x00, 0x02};
|
||||
public static final byte[] CREATE_FIELD_TYPE = { 0x00, 0x03};
|
||||
public static final byte[] MOD_FIELD_TYPE = { 0x00, 0x04};
|
||||
public static final byte[] ACCESS_FIELD_TYPE = { 0x00, 0x05};
|
||||
public static final byte[] EXPIRE_FIELD_TYPE = { 0x00, 0x06};
|
||||
public static final byte[] IMAGEID_FIELD_TYPE = { 0x00, 0x07};
|
||||
public static final byte[] LEVEL_FIELD_TYPE = { 0x00, 0x08};
|
||||
public static final byte[] FLAGS_FIELD_TYPE = { 0x00, 0x09};
|
||||
public static final byte[] END_FIELD_TYPE = Types.writeUByte(0xFFFF);
|
||||
public static final byte[] LONG_FOUR = { 0x00, 0x00, 0x00, 0x04};
|
||||
public static final byte[] GROUPID_FIELD_SIZE = LONG_FOUR;
|
||||
public static final byte[] DATE_FIELD_SIZE = { 0x00, 0x00, 0x00, 0x05};
|
||||
public static final byte[] IMAGEID_FIELD_SIZE = LONG_FOUR;
|
||||
public static final byte[] LEVEL_FIELD_SIZE = { 0x00, 0x00, 0x00, 0x02};
|
||||
public static final byte[] FLAGS_FIELD_SIZE = LONG_FOUR;
|
||||
public static final byte[] ZERO_FIELD_SIZE = { 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
|
||||
}
|
||||
@@ -127,6 +127,7 @@ public class ImporterV3 {
|
||||
if( newManager.algorithm == PwManager.ALGO_TWOFISH )
|
||||
throw new IOException( "TwoFish algorithm is not supported" );
|
||||
|
||||
newManager.dbHeader = hdr;
|
||||
|
||||
newManager.numKeyEncRounds = hdr.numKeyEncRounds;
|
||||
|
||||
@@ -175,6 +176,11 @@ public class ImporterV3 {
|
||||
byte[] plainContent = new byte[encryptedPartSize];
|
||||
System.arraycopy(filebuf, PwDbHeader.BUF_SIZE, plainContent, 0, encryptedPartSize);
|
||||
|
||||
// TODO: Delete Me
|
||||
newManager.postHeader = new byte[encryptedPartSize];
|
||||
System.arraycopy(filebuf, PwDbHeader.BUF_SIZE, newManager.postHeader, 0, encryptedPartSize);
|
||||
|
||||
|
||||
//if( pRepair == null ) {
|
||||
md = new SHA256Digest();
|
||||
md.update( filebuf, PwDbHeader.BUF_SIZE, encryptedPartSize );
|
||||
@@ -200,8 +206,8 @@ public class ImporterV3 {
|
||||
//KeePassMIDlet.logS ( newGrp.level + " " + newGrp.name );
|
||||
|
||||
// End-Group record. Save group and count it.
|
||||
//newManager.groups.add( newGrp );
|
||||
newManager.addGroup( newGrp );
|
||||
//newManager.groups.add( newGrp );
|
||||
newManager.addGroup( newGrp );
|
||||
newGrp = new PwGroup();
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ package org.phoneid.keepassj2me;
|
||||
// PhoneID
|
||||
import org.phoneid.*;
|
||||
|
||||
|
||||
// Java
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/*
|
||||
KeePass for J2ME
|
||||
* Copyright 2009 Brian Pellin.
|
||||
|
||||
This file was derived from
|
||||
|
||||
Copyright 2007 Naomaru Itoi <nao@phoneid.org>
|
||||
|
||||
@@ -8,57 +10,63 @@ This file was derived from
|
||||
Java clone of KeePass - A KeePass file viewer for Java
|
||||
Copyright 2006 Bill Zwicky <billzwicky@users.sourceforge.net>
|
||||
|
||||
This program 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; version 2
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.phoneid.keepassj2me;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Date;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* @author Brian Pellin <bpellin@gmail.com>
|
||||
* @author Naomaru Itoi <nao@phoneid.org>
|
||||
* @author Bill Zwicky <wrzwicky@pobox.com>
|
||||
* @author Dominik Reichl <dominik.reichl@t-online.de>
|
||||
*/
|
||||
public class PwGroup {
|
||||
public PwGroup() {
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** Size of byte buffer needed to hold this struct. */
|
||||
public static final int BUF_SIZE = 124;
|
||||
|
||||
/** Size of byte buffer needed to hold this struct. */
|
||||
public static final int BUF_SIZE = 124;
|
||||
// for tree traversing
|
||||
public Vector<PwGroup> childGroups = null;
|
||||
public Vector<PwEntry> childEntries = null;
|
||||
public PwGroup parent = null;
|
||||
|
||||
// for tree traversing
|
||||
public Vector<PwGroup> childGroups = null;
|
||||
public Vector<PwEntry> childEntries = null;
|
||||
public PwGroup parent = null;
|
||||
public int groupId;
|
||||
public int imageId;
|
||||
public String name;
|
||||
|
||||
public int groupId;
|
||||
public int imageId;
|
||||
public String name;
|
||||
public Date tCreation;
|
||||
public Date tLastMod;
|
||||
public Date tLastAccess;
|
||||
public Date tExpire;
|
||||
|
||||
public Date tCreation;
|
||||
public Date tLastMod;
|
||||
public Date tLastAccess;
|
||||
public Date tExpire;
|
||||
public int level; // short
|
||||
|
||||
public int level; //short
|
||||
|
||||
/** Used by KeePass internally, don't use */
|
||||
public int flags;
|
||||
/** Used by KeePass internally, don't use */
|
||||
public int flags;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ import com.android.keepass.keepasslib.InvalidKeyFileException;
|
||||
* @author Dominik Reichl <dominik.reichl@t-online.de>
|
||||
*/
|
||||
public class PwManager {
|
||||
// TODO: delete ME
|
||||
public byte[] postHeader;
|
||||
|
||||
// Constants
|
||||
// private static final int PWM_SESSION_KEY_SIZE = 12;
|
||||
@@ -82,6 +84,8 @@ public class PwManager {
|
||||
int algorithm;
|
||||
int numKeyEncRounds;
|
||||
|
||||
public PwDbHeader dbHeader;
|
||||
|
||||
// root group
|
||||
PwGroup rootGroup;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
package org.phoneid.keepassj2me;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
@@ -32,6 +33,38 @@ import java.util.Date;
|
||||
* @author Bill Zwicky <wrzwicky@pobox.com>
|
||||
*/
|
||||
public class Types {
|
||||
|
||||
public static long readUInt(byte buf[], int offset) {
|
||||
int firstByte = 0;
|
||||
int secondByte = 0;
|
||||
int thirdByte = 0;
|
||||
int fourthByte = 0;
|
||||
|
||||
firstByte = (0x000000FF & ((int)buf[offset]));
|
||||
secondByte = (0x000000FF & ((int)buf[offset+1]));
|
||||
thirdByte = (0x000000FF & ((int)buf[offset+2]));
|
||||
fourthByte = (0x000000FF & ((int)buf[offset+3]));
|
||||
|
||||
return ((long) (firstByte << 24
|
||||
| secondByte << 16
|
||||
| thirdByte << 8
|
||||
| fourthByte))
|
||||
& 0xFFFFFFFFL;
|
||||
|
||||
}
|
||||
|
||||
public static byte[] writeUInt(long val) {
|
||||
byte[] buf = new byte[4];
|
||||
|
||||
buf[0] = (byte) ((val & 0xFF000000L) >> 24);
|
||||
buf[1] = (byte) ((val & 0x00FF0000L) >> 16);
|
||||
buf[2] = (byte) ((val & 0x0000FF00L) >> 8);
|
||||
buf[3] = (byte) (val & 0x000000FFL);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a 32-bit value.
|
||||
*
|
||||
@@ -60,7 +93,12 @@ public class Types {
|
||||
buf[offset + 3] = (byte)((val >>> 24) & 0xFF);
|
||||
}
|
||||
|
||||
public static byte[] writeInt(int val) {
|
||||
byte[] buf = new byte[4];
|
||||
writeInt(val, buf, 0);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an unsigned 16-bit value.
|
||||
@@ -73,14 +111,47 @@ public class Types {
|
||||
return (buf[offset + 0] & 0xFF) + ((buf[offset + 1] & 0xFF) << 8);
|
||||
}
|
||||
|
||||
/** Write an unsigned 16-bit value
|
||||
*
|
||||
* @param val
|
||||
* @param buf
|
||||
* @param offset
|
||||
*/
|
||||
public static void writeShort(int val, byte[] buf, int offset) {
|
||||
buf[offset + 0] = (byte)(val & 0xFF);
|
||||
buf[offset + 1] = (byte)((val >>> 8) & 0xFF);
|
||||
}
|
||||
|
||||
public static byte[] writeShort(int val) {
|
||||
byte[] buf = new byte[2];
|
||||
|
||||
writeShort(val, buf, 0);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** Read an unsigned byte */
|
||||
public static int readUByte( byte[] buf, int offset ) {
|
||||
return ((int)buf[offset] & 0xFF);
|
||||
}
|
||||
|
||||
/** Write an unsigned byte
|
||||
*
|
||||
* @param val
|
||||
* @param buf
|
||||
* @param offset
|
||||
*/
|
||||
public static void writeUByte(int val, byte[] buf, int offset) {
|
||||
buf[offset] = (byte)(val & 0xFF);
|
||||
}
|
||||
|
||||
public static byte[] writeUByte(int val) {
|
||||
byte[] buf = new byte[2];
|
||||
|
||||
writeUByte(val, buf, 0);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return len of null-terminated string (i.e. distance to null)
|
||||
@@ -134,11 +205,33 @@ public class Types {
|
||||
int minute = ((dw4 & 0x0000000F) << 2) | (dw5 >> 6);
|
||||
int second = dw5 & 0x0000003F;
|
||||
|
||||
//Calendar time = Calendar.getInstance();
|
||||
//time.set( year, month, day, hour, minute, second );
|
||||
Calendar time = Calendar.getInstance();
|
||||
time.set( year, month, day, hour, minute, second );
|
||||
|
||||
//return time.getTime();
|
||||
return time.getTime();
|
||||
|
||||
return null;
|
||||
//return null;
|
||||
}
|
||||
|
||||
public static byte[] writeTime(Date date) {
|
||||
byte[] buf = new byte[5];
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
|
||||
int year = cal.get(Calendar.YEAR);
|
||||
int month = cal.get(Calendar.MONTH);
|
||||
int day = cal.get(Calendar.DAY_OF_MONTH);
|
||||
int hour = cal.get(Calendar.HOUR_OF_DAY);
|
||||
int minute = cal.get(Calendar.MINUTE);
|
||||
int second = cal.get(Calendar.SECOND);
|
||||
|
||||
buf[0] = (byte)((year >> 6) & 0x0000003F);
|
||||
buf[1] = (byte)(((year & 0x0000003F) << 2) | ((month >> 2) & 3) );
|
||||
buf[2] = (byte)(((month & 0x00000003) << 6) | ((day & 0x0000001F) << 1) | ((hour >> 4) & 0x00000001));
|
||||
buf[3] = (byte)(((hour & 0x0000000F) << 4) | ((minute >> 2) & 0x0000000F));
|
||||
buf[4] = (byte)(((minute & 0x00000003) << 6) | (second & 0x0000003F));
|
||||
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
BIN
tests/assets/test1.kdb
Normal file
BIN
tests/assets/test1.kdb
Normal file
Binary file not shown.
@@ -287,7 +287,7 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<!-- Uinstall the package from the default emulator -->
|
||||
<!-- Uninstall the package from the default emulator -->
|
||||
<target name="uninstall">
|
||||
<echo>Uninstalling ${application-package} from the default emulator...</echo>
|
||||
<exec executable="${adb}" failonerror="true">
|
||||
|
||||
61
tests/src/com/android/keepass/tests/PwEntryTest.java
Normal file
61
tests/src/com/android/keepass/tests/PwEntryTest.java
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2009 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.android.keepass.tests;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Calendar;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.phoneid.keepassj2me.PwEntry;
|
||||
|
||||
public class PwEntryTest extends TestCase {
|
||||
PwEntry mPE;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
mPE = TestData.GetTest1().entries.get(0);
|
||||
|
||||
}
|
||||
|
||||
public void testName() {
|
||||
assertTrue("Name was " + mPE.title, mPE.title.equals("Amazon"));
|
||||
}
|
||||
|
||||
public void testPassword() throws UnsupportedEncodingException {
|
||||
String sPass = "12345";
|
||||
byte[] password = sPass.getBytes("UTF-8");
|
||||
|
||||
assertArrayEquals(password, mPE.getPassword());
|
||||
}
|
||||
|
||||
public void testCreation() {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(mPE.tCreation);
|
||||
|
||||
assertTrue("Incorrect year.", cal.get(Calendar.YEAR) == 2009);
|
||||
assertTrue("Incorrect month.", cal.get(Calendar.MONTH) == 4);
|
||||
assertTrue("Incorrect day.", cal.get(Calendar.DAY_OF_MONTH) == 23);
|
||||
}
|
||||
|
||||
}
|
||||
99
tests/src/com/android/keepass/tests/PwGroupOutputTest.java
Normal file
99
tests/src/com/android/keepass/tests/PwGroupOutputTest.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2009 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.android.keepass.tests;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.DigestOutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.phoneid.keepassj2me.PwEntry;
|
||||
import org.phoneid.keepassj2me.PwGroup;
|
||||
import org.phoneid.keepassj2me.PwManager;
|
||||
|
||||
import com.android.keepass.keepasslib.PwEntryOutput;
|
||||
import com.android.keepass.keepasslib.PwGroupOutput;
|
||||
|
||||
public class PwGroupOutputTest extends TestCase {
|
||||
PwManager mPM;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
mPM = TestData.GetTest1();
|
||||
|
||||
}
|
||||
|
||||
public void testPlainContent() throws IOException {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
|
||||
// Groups
|
||||
for (int i = 0; i < mPM.groups.size(); i++ ) {
|
||||
PwGroup pg = mPM.groups.get(i);
|
||||
PwGroupOutput pgo = new PwGroupOutput(pg, bos);
|
||||
pgo.output();
|
||||
}
|
||||
|
||||
// Entries
|
||||
for (int i = 0; i < mPM.entries.size(); i++ ) {
|
||||
PwEntry pe = mPM.entries.get(i);
|
||||
PwEntryOutput peo = new PwEntryOutput(pe, bos);
|
||||
peo.output();
|
||||
}
|
||||
|
||||
byte[] buf = bos.toByteArray();
|
||||
for (int i = 0; i < buf.length; i++) {
|
||||
assertEquals("Difference at byte " + i, mPM.postHeader[i], buf[i]);
|
||||
}
|
||||
|
||||
//assertArrayEquals(mPM.postHeader, bos.toByteArray());
|
||||
|
||||
}
|
||||
|
||||
public void testChecksum() throws NoSuchAlgorithmException, IOException {
|
||||
FileOutputStream fos = new FileOutputStream("/dev/null");
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
|
||||
DigestOutputStream dos = new DigestOutputStream(fos, md);
|
||||
|
||||
// Groups
|
||||
for (int i = 0; i < mPM.groups.size(); i++ ) {
|
||||
PwGroup pg = mPM.groups.get(i);
|
||||
PwGroupOutput pgo = new PwGroupOutput(pg, dos);
|
||||
pgo.output();
|
||||
}
|
||||
|
||||
// Entries
|
||||
for (int i = 0; i < mPM.entries.size(); i++ ) {
|
||||
PwEntry pe = mPM.entries.get(i);
|
||||
PwEntryOutput peo = new PwEntryOutput(pe, dos);
|
||||
peo.output();
|
||||
}
|
||||
|
||||
assertArrayEquals("Hash of groups and entries failed.", md.digest(), mPM.dbHeader.contentsHash);
|
||||
}
|
||||
}
|
||||
42
tests/src/com/android/keepass/tests/PwGroupTest.java
Normal file
42
tests/src/com/android/keepass/tests/PwGroupTest.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2009 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.android.keepass.tests;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.phoneid.keepassj2me.PwGroup;
|
||||
|
||||
public class PwGroupTest extends TestCase {
|
||||
|
||||
PwGroup mPG;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
mPG = TestData.GetTest1().groups.get(0);
|
||||
|
||||
}
|
||||
|
||||
public void testGroupName() {
|
||||
assertTrue("Name was " + mPG.name, mPG.name.equals("Internet"));
|
||||
}
|
||||
}
|
||||
|
||||
48
tests/src/com/android/keepass/tests/TestData.java
Normal file
48
tests/src/com/android/keepass/tests/TestData.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2009 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.android.keepass.tests;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bouncycastle1.crypto.InvalidCipherTextException;
|
||||
import org.phoneid.keepassj2me.ImporterV3;
|
||||
import org.phoneid.keepassj2me.PwManager;
|
||||
|
||||
import com.android.keepass.keepasslib.InvalidKeyFileException;
|
||||
|
||||
public class TestData {
|
||||
private static PwManager test1;
|
||||
|
||||
public static PwManager GetTest1() throws InvalidCipherTextException, IOException, InvalidKeyFileException {
|
||||
|
||||
if ( test1 == null ) {
|
||||
FileInputStream fis = new FileInputStream("/sdcard/test1.kdb");
|
||||
ImporterV3 importer = new ImporterV3();
|
||||
test1 = importer.openDatabase(fis, "12345", "");
|
||||
if (test1 != null) {
|
||||
test1.constructTree(null);
|
||||
}
|
||||
}
|
||||
|
||||
return test1;
|
||||
}
|
||||
}
|
||||
@@ -25,29 +25,86 @@ import static org.junit.Assert.*;
|
||||
|
||||
public class TypesTest extends TestCase {
|
||||
|
||||
public void testReadWriteInt() {
|
||||
byte[] orig = new byte[8];
|
||||
byte[] dest = new byte[8];
|
||||
|
||||
public void testReadWriteIntZero() {
|
||||
testReadWriteInt((byte) 0);
|
||||
}
|
||||
|
||||
public void testReadWriteIntMin() {
|
||||
testReadWriteInt(Byte.MIN_VALUE);
|
||||
}
|
||||
|
||||
public void testReadWriteIntMax() {
|
||||
testReadWriteInt(Byte.MAX_VALUE);
|
||||
}
|
||||
|
||||
private void testReadWriteInt(byte value) {
|
||||
byte[] orig = new byte[4];
|
||||
byte[] dest = new byte[4];
|
||||
|
||||
for (int i = 0; i < 4; i++ ) {
|
||||
orig[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 4; i < 8; i++ ) {
|
||||
orig[4] = Byte.MAX_VALUE;
|
||||
|
||||
}
|
||||
setArray(orig, value, 0, 4);
|
||||
|
||||
int one = Types.readInt(orig, 0);
|
||||
int two = Types.readInt(orig, 4);
|
||||
|
||||
Types.writeInt(one, dest, 0);
|
||||
Types.writeInt(two, dest, 4);
|
||||
|
||||
assertArrayEquals(orig, dest);
|
||||
|
||||
}
|
||||
|
||||
private void setArray(byte[] buf, byte value, int offset, int size) {
|
||||
for (int i = offset; i < offset + size; i++) {
|
||||
buf[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void testReadWriteShortZero() {
|
||||
testReadWriteShort((byte) 0);
|
||||
}
|
||||
|
||||
public void testReadWriteShortMin() {
|
||||
testReadWriteShort(Byte.MIN_VALUE);
|
||||
}
|
||||
|
||||
public void testReadWriteShortMax() {
|
||||
testReadWriteShort(Byte.MAX_VALUE);
|
||||
}
|
||||
|
||||
private void testReadWriteShort(byte value) {
|
||||
byte[] orig = new byte[2];
|
||||
byte[] dest = new byte[2];
|
||||
|
||||
setArray(orig, value, 0, 2);
|
||||
|
||||
int one = Types.readShort(orig, 0);
|
||||
Types.writeShort(one, dest, 0);
|
||||
}
|
||||
|
||||
public void testReadWriteByteZero() {
|
||||
testReadWriteByte((byte) 0);
|
||||
}
|
||||
|
||||
public void testReadWriteByteMin() {
|
||||
testReadWriteByte(Byte.MIN_VALUE);
|
||||
}
|
||||
|
||||
public void testReadWriteByteMax() {
|
||||
testReadWriteShort(Byte.MAX_VALUE);
|
||||
}
|
||||
|
||||
private void testReadWriteByte(byte value) {
|
||||
byte[] orig = new byte[1];
|
||||
byte[] dest = new byte[1];
|
||||
|
||||
setArray(orig, value, 0, 1);
|
||||
|
||||
int one = Types.readUByte(orig, 0);
|
||||
Types.writeUByte(one, dest, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user