mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-16 22:05:05 -05:00
layout adjustments, force portrait layout for EncryptFileActivity for now, (En|De)cryptFileActivity can now handle symmetric algorithms
This commit is contained in:
parent
ab6c884bdf
commit
0e14dcb290
@ -74,6 +74,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".EncryptFileActivity"
|
android:name=".EncryptFileActivity"
|
||||||
android:label="@string/title_encryptFile"
|
android:label="@string/title_encryptFile"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard">
|
android:configChanges="keyboardHidden|orientation|keyboard">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
@ -21,204 +21,213 @@
|
|||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingTop="5dip">
|
android:paddingTop="5dip">
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="5dip"
|
|
||||||
android:paddingRight="5dip">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label_filename"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
|
||||||
android:layout_width="50dip"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/label_file"/>
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/filename"
|
|
||||||
android:layout_width="0dip"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"/>
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/btn_browse"
|
|
||||||
android:src="@drawable/ic_launcher_folder_small"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/ascii_armour"
|
|
||||||
android:text="@string/ascii_armour"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"/>
|
|
||||||
|
|
||||||
<TabHost
|
|
||||||
android:id="@+id/tab_host"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="0dip">
|
|
||||||
|
|
||||||
<TabWidget
|
|
||||||
android:id="@android:id/tabs"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="65dip"/>
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@android:id/tabcontent"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:paddingTop="65dip">
|
|
||||||
|
|
||||||
<!-- -->
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/tab_asymmetric"
|
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="5dip">
|
||||||
|
|
||||||
<LinearLayout
|
<TextView
|
||||||
android:layout_width="fill_parent"
|
android:id="@+id/label_filename"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:layout_width="50dip"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingBottom="3dip"
|
android:text="@string/label_file"/>
|
||||||
android:orientation="horizontal">
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/filename"
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"/>
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_browse"
|
||||||
|
android:src="@drawable/ic_launcher_folder_small"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TableLayout
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:stretchColumns="1"
|
||||||
|
android:paddingLeft="6dip">
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
<TextView android:id="@+id/label_algorithm"
|
||||||
|
android:text="Algorithm:"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingRight="10dip"/>
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/algorithm"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/label_ascii_armour"
|
||||||
|
android:text="@string/ascii_armour"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingRight="10dip"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"/>
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:text="@string/sign"
|
android:id="@+id/ascii_armour"
|
||||||
android:id="@+id/sign"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_gravity="right|center_vertical"/>
|
||||||
android:layout_gravity="center_vertical"/>
|
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
</TableLayout>
|
||||||
|
|
||||||
|
<TabHost
|
||||||
|
android:id="@+id/tab_host"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="0dip">
|
||||||
|
|
||||||
|
<TabWidget
|
||||||
|
android:id="@android:id/tabs"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="65dip"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@android:id/tabcontent"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:paddingTop="65dip">
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
android:id="@+id/tab_asymmetric"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_height="fill_parent"
|
||||||
android:paddingRight="5dip">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="3dip"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:text="@string/sign"
|
||||||
|
android:id="@+id/sign"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingRight="5dip">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/main_user_id"
|
||||||
|
android:text="Main User Id"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="right"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/main_user_id_rest"
|
||||||
|
android:text="Main User Id Rest"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="right"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/separator"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="1dip"
|
||||||
|
android:background="?android:attr/listDivider"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/main_user_id"
|
android:id="@+id/label_encrypt_keys"
|
||||||
android:text="Main User Id"
|
android:text="@string/label_encrypt_keys"
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"/>
|
||||||
android:layout_gravity="right"/>
|
|
||||||
|
<ListView
|
||||||
|
android:id="@+id/public_key_list"
|
||||||
|
android:choiceMode="multipleChoice"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
<!-- -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/tab_symmetric"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingTop="3dip">
|
||||||
|
|
||||||
|
<TableLayout
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:stretchColumns="1"
|
||||||
|
android:paddingLeft="6dip">
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
<TextView android:id="@+id/label_pass_phrase"
|
||||||
|
android:text="Pass phrase"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingRight="10dip"/>
|
||||||
|
|
||||||
|
<EditText android:id="@+id/pass_phrase"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:inputType="textPassword"/>
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
|
||||||
|
<TextView android:id="@+id/label_pass_phrase_again"
|
||||||
|
android:text="Again:"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingRight="10dip"/>
|
||||||
|
|
||||||
|
<EditText android:id="@+id/pass_phrase_again"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:inputType="textPassword"/>
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
</TableLayout>
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/main_user_id_rest"
|
|
||||||
android:text="Main User Id Rest"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="right"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<View
|
</TabHost>
|
||||||
android:id="@+id/separator"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="1dip"
|
|
||||||
android:background="?android:attr/listDivider"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label_encrypt_keys"
|
|
||||||
android:text="@string/label_encrypt_keys"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<ListView
|
|
||||||
android:id="@+id/public_key_list"
|
|
||||||
android:choiceMode="multipleChoice"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="0dip"
|
|
||||||
android:layout_weight="1"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
<!-- -->
|
|
||||||
<ScrollView
|
|
||||||
android:id="@+id/tab_symmetric"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:fillViewport="true">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingTop="3dip">
|
|
||||||
|
|
||||||
<TableLayout
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:stretchColumns="1"
|
|
||||||
android:layout_marginRight="?android:attr/scrollbarSize"
|
|
||||||
android:paddingLeft="6dip">
|
|
||||||
|
|
||||||
<TableRow
|
|
||||||
android:layout_marginBottom="5dip">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/label_algorithm"
|
|
||||||
android:text="Algorithm:"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"/>
|
|
||||||
|
|
||||||
<Spinner
|
|
||||||
android:id="@+id/algorithm"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView android:id="@+id/label_pass_phrase"
|
|
||||||
android:text="Pass phrase"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"/>
|
|
||||||
|
|
||||||
<EditText android:id="@+id/pass_phrase"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:inputType="textPassword"/>
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView android:id="@+id/label_pass_phrase_again"
|
|
||||||
android:text="Again:"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"/>
|
|
||||||
|
|
||||||
<EditText android:id="@+id/pass_phrase_again"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:inputType="textPassword"/>
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
</TableLayout>
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
</TabHost>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
|
@ -45,8 +45,8 @@
|
|||||||
<string name="btn_save">Save</string>
|
<string name="btn_save">Save</string>
|
||||||
<string name="btn_doNotSave">Cancel</string>
|
<string name="btn_doNotSave">Cancel</string>
|
||||||
|
|
||||||
<string name="tab_symmetric">Symmetric</string>
|
<string name="tab_symmetric">Use Pass Phrase</string>
|
||||||
<string name="tab_asymmetric">Asymmetric</string>
|
<string name="tab_asymmetric">Use Public Key</string>
|
||||||
|
|
||||||
<string name="menu_about">About</string>
|
<string name="menu_about">About</string>
|
||||||
<string name="menu_addAccount">Add GMail Account</string>
|
<string name="menu_addAccount">Add GMail Account</string>
|
||||||
|
@ -41,6 +41,7 @@ import java.util.Comparator;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@ -66,6 +67,7 @@ import org.bouncycastle2.openpgp.PGPLiteralDataGenerator;
|
|||||||
import org.bouncycastle2.openpgp.PGPObjectFactory;
|
import org.bouncycastle2.openpgp.PGPObjectFactory;
|
||||||
import org.bouncycastle2.openpgp.PGPOnePassSignature;
|
import org.bouncycastle2.openpgp.PGPOnePassSignature;
|
||||||
import org.bouncycastle2.openpgp.PGPOnePassSignatureList;
|
import org.bouncycastle2.openpgp.PGPOnePassSignatureList;
|
||||||
|
import org.bouncycastle2.openpgp.PGPPBEEncryptedData;
|
||||||
import org.bouncycastle2.openpgp.PGPPrivateKey;
|
import org.bouncycastle2.openpgp.PGPPrivateKey;
|
||||||
import org.bouncycastle2.openpgp.PGPPublicKey;
|
import org.bouncycastle2.openpgp.PGPPublicKey;
|
||||||
import org.bouncycastle2.openpgp.PGPPublicKeyEncryptedData;
|
import org.bouncycastle2.openpgp.PGPPublicKeyEncryptedData;
|
||||||
@ -1361,24 +1363,60 @@ public class Apg {
|
|||||||
throw new GeneralException("data not valid encryption data");
|
throw new GeneralException("data not valid encryption data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: currently we always only look at the first known key
|
||||||
// find the secret key
|
// find the secret key
|
||||||
PGPSecretKey secretKey = null;
|
PGPSecretKey secretKey = null;
|
||||||
for (PGPPublicKeyEncryptedData pbe :
|
Iterator it = enc.getEncryptedDataObjects();
|
||||||
new IterableIterator<PGPPublicKeyEncryptedData>(enc.getEncryptedDataObjects())) {
|
while (it.hasNext()) {
|
||||||
secretKey = findSecretKey(pbe.getKeyID());
|
Object obj = it.next();
|
||||||
if (secretKey != null) {
|
if (obj instanceof PGPPublicKeyEncryptedData) {
|
||||||
break;
|
PGPPublicKeyEncryptedData pbe = (PGPPublicKeyEncryptedData) obj;
|
||||||
|
secretKey = findSecretKey(pbe.getKeyID());
|
||||||
|
if (secretKey != null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (secretKey == null) {
|
if (secretKey == null) {
|
||||||
throw new GeneralException("couldn't find a secret key to decrypt");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return secretKey.getKeyID();
|
return secretKey.getKeyID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasSymmetricEncryption(InputStream inStream)
|
||||||
|
throws GeneralException, IOException {
|
||||||
|
InputStream in = PGPUtil.getDecoderStream(inStream);
|
||||||
|
PGPObjectFactory pgpF = new PGPObjectFactory(in);
|
||||||
|
PGPEncryptedDataList enc;
|
||||||
|
Object o = pgpF.nextObject();
|
||||||
|
|
||||||
|
// the first object might be a PGP marker packet.
|
||||||
|
if (o instanceof PGPEncryptedDataList) {
|
||||||
|
enc = (PGPEncryptedDataList) o;
|
||||||
|
} else {
|
||||||
|
enc = (PGPEncryptedDataList) pgpF.nextObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enc == null) {
|
||||||
|
throw new GeneralException("data not valid encryption data");
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator it = enc.getEncryptedDataObjects();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Object obj = it.next();
|
||||||
|
if (obj instanceof PGPPBEEncryptedData) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static Bundle decrypt(InputStream inStream, OutputStream outStream,
|
public static Bundle decrypt(InputStream inStream, OutputStream outStream,
|
||||||
String passPhrase, ProgressDialogUpdater progress)
|
String passPhrase, ProgressDialogUpdater progress,
|
||||||
|
boolean assumeSymmetric)
|
||||||
throws IOException, GeneralException, PGPException, SignatureException {
|
throws IOException, GeneralException, PGPException, SignatureException {
|
||||||
Bundle returnData = new Bundle();
|
Bundle returnData = new Bundle();
|
||||||
InputStream in = PGPUtil.getDecoderStream(inStream);
|
InputStream in = PGPUtil.getDecoderStream(inStream);
|
||||||
@ -1399,32 +1437,66 @@ public class Apg {
|
|||||||
throw new GeneralException("data not valid encryption data");
|
throw new GeneralException("data not valid encryption data");
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.setProgress("finding key...", 10, 100);
|
InputStream clear = null;
|
||||||
// find the secret key
|
PGPEncryptedData encryptedData = null;
|
||||||
PGPPublicKeyEncryptedData pbe = null;
|
|
||||||
PGPSecretKey secretKey = null;
|
// TODO: currently we always only look at the first known key or symmetric encryption,
|
||||||
for (PGPPublicKeyEncryptedData encData :
|
// there might be more...
|
||||||
new IterableIterator<PGPPublicKeyEncryptedData>(enc.getEncryptedDataObjects())) {
|
if (assumeSymmetric) {
|
||||||
secretKey = findSecretKey(encData.getKeyID());
|
PGPPBEEncryptedData pbe = null;
|
||||||
if (secretKey != null) {
|
Iterator it = enc.getEncryptedDataObjects();
|
||||||
pbe = encData;
|
// find secret key
|
||||||
break;
|
while (it.hasNext()) {
|
||||||
|
Object obj = it.next();
|
||||||
|
if (obj instanceof PGPPBEEncryptedData) {
|
||||||
|
pbe = (PGPPBEEncryptedData) obj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (secretKey == null) {
|
if (pbe == null) {
|
||||||
throw new GeneralException("couldn't find a secret key to decrypt");
|
throw new GeneralException("couldn't find a packet with symmetric encryption");
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.setProgress("decrypting data...", 20, 100);
|
||||||
|
clear = pbe.getDataStream(passPhrase.toCharArray(), new BouncyCastleProvider());
|
||||||
|
encryptedData = pbe;
|
||||||
|
} else {
|
||||||
|
progress.setProgress("finding key...", 10, 100);
|
||||||
|
PGPPublicKeyEncryptedData pbe = null;
|
||||||
|
PGPSecretKey secretKey = null;
|
||||||
|
Iterator it = enc.getEncryptedDataObjects();
|
||||||
|
// find secret key
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Object obj = it.next();
|
||||||
|
if (obj instanceof PGPPublicKeyEncryptedData) {
|
||||||
|
PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
|
||||||
|
secretKey = findSecretKey(encData.getKeyID());
|
||||||
|
if (secretKey != null) {
|
||||||
|
pbe = encData;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secretKey == null) {
|
||||||
|
throw new GeneralException("couldn't find a secret key to decrypt");
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.setProgress("extracting key...", 20, 100);
|
||||||
|
PGPPrivateKey privateKey = null;
|
||||||
|
try {
|
||||||
|
privateKey = secretKey.extractPrivateKey(passPhrase.toCharArray(),
|
||||||
|
new BouncyCastleProvider());
|
||||||
|
} catch (PGPException e) {
|
||||||
|
throw new PGPException("wrong pass phrase");
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.setProgress("decrypting data...", 30, 100);
|
||||||
|
clear = pbe.getDataStream(privateKey, new BouncyCastleProvider());
|
||||||
|
encryptedData = pbe;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.setProgress("extracting key...", 20, 100);
|
|
||||||
PGPPrivateKey privateKey = null;
|
|
||||||
try {
|
|
||||||
privateKey = secretKey.extractPrivateKey(passPhrase.toCharArray(),
|
|
||||||
new BouncyCastleProvider());
|
|
||||||
} catch (PGPException e) {
|
|
||||||
throw new PGPException("wrong pass phrase");
|
|
||||||
}
|
|
||||||
progress.setProgress("decrypting data...", 30, 100);
|
|
||||||
InputStream clear = pbe.getDataStream(privateKey, new BouncyCastleProvider());
|
|
||||||
PGPObjectFactory plainFact = new PGPObjectFactory(clear);
|
PGPObjectFactory plainFact = new PGPObjectFactory(clear);
|
||||||
Object dataChunk = plainFact.nextObject();
|
Object dataChunk = plainFact.nextObject();
|
||||||
PGPOnePassSignature signature = null;
|
PGPOnePassSignature signature = null;
|
||||||
@ -1511,15 +1583,15 @@ public class Apg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add integrity somewhere
|
// TODO: add integrity somewhere
|
||||||
if (pbe.isIntegrityProtected()) {
|
if (encryptedData.isIntegrityProtected()) {
|
||||||
progress.setProgress("verifying integrity...", 90, 100);
|
progress.setProgress("verifying integrity...", 90, 100);
|
||||||
if (!pbe.verify()) {
|
if (encryptedData.verify()) {
|
||||||
System.err.println("message failed integrity check");
|
// passed
|
||||||
} else {
|
} else {
|
||||||
System.err.println("message integrity check passed");
|
// failed
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.err.println("no message integrity check");
|
// no integrity check
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.setProgress("done.", 100, 100);
|
progress.setProgress("done.", 100, 100);
|
||||||
|
@ -26,9 +26,6 @@ import android.app.Dialog;
|
|||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.text.method.PasswordTransformationMethod;
|
import android.text.method.PasswordTransformationMethod;
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnKeyListener;
|
|
||||||
import android.view.ViewGroup.LayoutParams;
|
import android.view.ViewGroup.LayoutParams;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
@ -43,36 +40,25 @@ public class AskForSecretKeyPassPhrase {
|
|||||||
PassPhraseCallbackInterface callback) {
|
PassPhraseCallbackInterface callback) {
|
||||||
AlertDialog.Builder alert = new AlertDialog.Builder(context);
|
AlertDialog.Builder alert = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
final PGPSecretKey secretKey =
|
|
||||||
Apg.getMasterKey(Apg.findSecretKeyRing(secretKeyId));
|
|
||||||
if (secretKey == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String userId = Apg.getMainUserIdSafe(context, secretKey);
|
|
||||||
|
|
||||||
alert.setTitle(R.string.title_authentification);
|
alert.setTitle(R.string.title_authentification);
|
||||||
alert.setMessage("Pass phrase for " + userId);
|
|
||||||
|
final PGPSecretKey secretKey;
|
||||||
|
|
||||||
|
if (secretKeyId == 0) {
|
||||||
|
secretKey = null;
|
||||||
|
alert.setMessage("Pass phrase");
|
||||||
|
} else {
|
||||||
|
secretKey = Apg.getMasterKey(Apg.findSecretKeyRing(secretKeyId));
|
||||||
|
if (secretKey == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String userId = Apg.getMainUserIdSafe(context, secretKey);
|
||||||
|
alert.setMessage("Pass phrase for " + userId);
|
||||||
|
}
|
||||||
|
|
||||||
final EditText input = new EditText(context);
|
final EditText input = new EditText(context);
|
||||||
input.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
input.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||||
input.setTransformationMethod(new PasswordTransformationMethod());
|
input.setTransformationMethod(new PasswordTransformationMethod());
|
||||||
input.setOnKeyListener(new OnKeyListener() {
|
|
||||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
|
||||||
// If the event is a key-down event on the "enter" button
|
|
||||||
if (event.getAction() == KeyEvent.ACTION_DOWN &&
|
|
||||||
keyCode == KeyEvent.KEYCODE_ENTER) {
|
|
||||||
try {
|
|
||||||
((AlertDialog) v.getParent()).getButton(AlertDialog.BUTTON_POSITIVE)
|
|
||||||
.performClick();
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
// don't do anything if we're not in that dialog
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 5dip padding
|
// 5dip padding
|
||||||
int padding = (int) (10 * context.getResources().getDisplayMetrics().densityDpi / 160);
|
int padding = (int) (10 * context.getResources().getDisplayMetrics().densityDpi / 160);
|
||||||
LinearLayout layout = new LinearLayout(context);
|
LinearLayout layout = new LinearLayout(context);
|
||||||
@ -91,14 +77,16 @@ public class AskForSecretKeyPassPhrase {
|
|||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
activity.removeDialog(Id.dialog.pass_phrase);
|
activity.removeDialog(Id.dialog.pass_phrase);
|
||||||
String passPhrase = "" + input.getText();
|
String passPhrase = "" + input.getText();
|
||||||
try {
|
if (secretKey != null) {
|
||||||
secretKey.extractPrivateKey(passPhrase.toCharArray(),
|
try {
|
||||||
new BouncyCastleProvider());
|
secretKey.extractPrivateKey(passPhrase.toCharArray(),
|
||||||
} catch (PGPException e) {
|
new BouncyCastleProvider());
|
||||||
Toast.makeText(activity,
|
} catch (PGPException e) {
|
||||||
R.string.wrong_pass_phrase,
|
Toast.makeText(activity,
|
||||||
Toast.LENGTH_SHORT).show();
|
R.string.wrong_pass_phrase,
|
||||||
return;
|
Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cb.passPhraseCallback(passPhrase);
|
cb.passPhraseCallback(passPhrase);
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,8 @@ public class DecryptFileActivity extends BaseActivity {
|
|||||||
private String mInputFilename = null;
|
private String mInputFilename = null;
|
||||||
private String mOutputFilename = null;
|
private String mOutputFilename = null;
|
||||||
|
|
||||||
|
private boolean mAssumeSymmetricEncryption = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@ -128,6 +130,16 @@ public class DecryptFileActivity extends BaseActivity {
|
|||||||
try {
|
try {
|
||||||
InputStream in = new FileInputStream(mInputFilename);
|
InputStream in = new FileInputStream(mInputFilename);
|
||||||
setSecretKeyId(Apg.getDecryptionKeyId(in));
|
setSecretKeyId(Apg.getDecryptionKeyId(in));
|
||||||
|
if (getSecretKeyId() == 0) {
|
||||||
|
// reopen the file to check whether there's symmetric encryption data in there
|
||||||
|
in = new FileInputStream(mInputFilename);
|
||||||
|
if (!Apg.hasSymmetricEncryption(in)) {
|
||||||
|
throw new Apg.GeneralException("no suitable keys found");
|
||||||
|
}
|
||||||
|
mAssumeSymmetricEncryption = true;
|
||||||
|
} else {
|
||||||
|
mAssumeSymmetricEncryption = false;
|
||||||
|
}
|
||||||
showDialog(Id.dialog.pass_phrase);
|
showDialog(Id.dialog.pass_phrase);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
error = "file not found: " + e.getLocalizedMessage();
|
error = "file not found: " + e.getLocalizedMessage();
|
||||||
@ -168,7 +180,7 @@ public class DecryptFileActivity extends BaseActivity {
|
|||||||
InputStream in = new FileInputStream(mInputFilename);
|
InputStream in = new FileInputStream(mInputFilename);
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
data = Apg.decrypt(in, out, Apg.getPassPhrase(), this);
|
data = Apg.decrypt(in, out, Apg.getPassPhrase(), this, mAssumeSymmetricEncryption);
|
||||||
|
|
||||||
out.close();
|
out.close();
|
||||||
OutputStream fileOut = new FileOutputStream(mOutputFilename);
|
OutputStream fileOut = new FileOutputStream(mOutputFilename);
|
||||||
|
@ -204,7 +204,7 @@ public class DecryptMessageActivity extends BaseActivity {
|
|||||||
if (mSignedOnly) {
|
if (mSignedOnly) {
|
||||||
data = Apg.verifyText(in, out, this);
|
data = Apg.verifyText(in, out, this);
|
||||||
} else {
|
} else {
|
||||||
data = Apg.decrypt(in, out, Apg.getPassPhrase(), this);
|
data = Apg.decrypt(in, out, Apg.getPassPhrase(), this, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.close();
|
out.close();
|
||||||
|
@ -101,7 +101,7 @@ public class EncryptFileActivity extends BaseActivity {
|
|||||||
|
|
||||||
TabSpec ts2 = mTabHost.newTabSpec(TAB_SYMMETRIC);
|
TabSpec ts2 = mTabHost.newTabSpec(TAB_SYMMETRIC);
|
||||||
ts2.setIndicator(getString(R.string.tab_symmetric),
|
ts2.setIndicator(getString(R.string.tab_symmetric),
|
||||||
getResources().getDrawable(R.drawable.encrypted));
|
getResources().getDrawable(R.drawable.key));
|
||||||
ts2.setContent(R.id.tab_symmetric);
|
ts2.setContent(R.id.tab_symmetric);
|
||||||
mTabHost.addTab(ts2);
|
mTabHost.addTab(ts2);
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ public class MainActivity extends BaseActivity {
|
|||||||
new SpannableString("Read the warnings!\n\n" +
|
new SpannableString("Read the warnings!\n\n" +
|
||||||
"Changes:\n" +
|
"Changes:\n" +
|
||||||
" * OI File Manager support\n" +
|
" * OI File Manager support\n" +
|
||||||
" * file encryption\n" +
|
" * file encryption/decryption\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"WARNING: be careful editing your existing keys, as they " +
|
"WARNING: be careful editing your existing keys, as they " +
|
||||||
"WILL be stripped of certificates right now.\n" +
|
"WILL be stripped of certificates right now.\n" +
|
||||||
|
Loading…
Reference in New Issue
Block a user