From 212ee222c3cf66adda0842176a17f9302549f51b Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sun, 2 Feb 2014 22:14:07 +0000 Subject: replace spinner with non-functioning checkboxes --- .../keychain/ui/widget/KeyEditor.java | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 6c265057e..16e868a2c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -89,18 +89,18 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mKeyId = (TextView) findViewById(R.id.keyId); mCreationDate = (TextView) findViewById(R.id.creation); mExpiryDateButton = (BootstrapButton) findViewById(R.id.expiry); - mUsage = (Spinner) findViewById(R.id.usage); - Choice choices[] = { - new Choice(Id.choice.usage.sign_only, getResources().getString( - R.string.choice_sign_only)), - new Choice(Id.choice.usage.encrypt_only, getResources().getString( - R.string.choice_encrypt_only)), - new Choice(Id.choice.usage.sign_and_encrypt, getResources().getString( - R.string.choice_sign_and_encrypt)), }; - ArrayAdapter adapter = new ArrayAdapter(getContext(), - android.R.layout.simple_spinner_item, choices); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - mUsage.setAdapter(adapter); + //mUsage = (Spinner) findViewById(R.id.usage); + //Choice choices[] = { + // new Choice(Id.choice.usage.sign_only, getResources().getString( + // R.string.choice_sign_only)), + // new Choice(Id.choice.usage.encrypt_only, getResources().getString( + // R.string.choice_encrypt_only)), + // new Choice(Id.choice.usage.sign_and_encrypt, getResources().getString( + // R.string.choice_sign_and_encrypt)), }; + //ArrayAdapter adapter = new ArrayAdapter(getContext(), + // android.R.layout.simple_spinner_item, choices); + //adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + //mUsage.setAdapter(adapter); mDeleteButton = (BootstrapButton) findViewById(R.id.delete); mDeleteButton.setOnClickListener(this); @@ -139,7 +139,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { public void setCanEdit(boolean bCanEdit) { if (!bCanEdit) { mDeleteButton.setVisibility(View.INVISIBLE); - mUsage.setEnabled(false); + //mUsage.setEnabled(false); mExpiryDateButton.setEnabled(false); } } @@ -161,22 +161,22 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { boolean isElGamalKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT); boolean isDSAKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.DSA); if (!isElGamalKey) { - choices.add(new Choice(Id.choice.usage.sign_only, getResources().getString( - R.string.choice_sign_only))); + //choices.add(new Choice(Id.choice.usage.sign_only, getResources().getString( + // R.string.choice_sign_only))); } if (!mIsMasterKey && !isDSAKey) { - choices.add(new Choice(Id.choice.usage.encrypt_only, getResources().getString( - R.string.choice_encrypt_only))); + //choices.add(new Choice(Id.choice.usage.encrypt_only, getResources().getString( + // R.string.choice_encrypt_only))); } if (!isElGamalKey && !isDSAKey) { - choices.add(new Choice(Id.choice.usage.sign_and_encrypt, getResources().getString( - R.string.choice_sign_and_encrypt))); + //choices.add(new Choice(Id.choice.usage.sign_and_encrypt, getResources().getString( + // R.string.choice_sign_and_encrypt))); } ArrayAdapter adapter = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_item, choices); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - mUsage.setAdapter(adapter); + //mUsage.setAdapter(adapter); // Set value in choice dropdown to key int selectId = 0; @@ -198,7 +198,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { for (int i = 0; i < choices.size(); ++i) { if (choices.get(i).getId() == selectId) { - mUsage.setSelection(i); + //mUsage.setSelection(i); break; } } @@ -249,7 +249,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { } public int getUsage() { - return ((Choice) mUsage.getSelectedItem()).getId(); + return 1; //((Choice) mUsage.getSelectedItem()).getId(); } } -- cgit v1.2.3 From a90b748611126cd122e39ef944f4c268798419f0 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sun, 2 Feb 2014 23:56:53 +0000 Subject: set checkboxes from key properties --- .../keychain/ui/widget/KeyEditor.java | 74 +++++++++++----------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 16e868a2c..f845b53a7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -39,9 +39,12 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ArrayAdapter; +import android.widget.CheckBox; import android.widget.DatePicker; import android.widget.LinearLayout; import android.widget.Spinner; +import android.widget.TableLayout; +import android.widget.TableRow; import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; @@ -59,6 +62,10 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { TextView mCreationDate; BootstrapButton mExpiryDateButton; GregorianCalendar mExpiryDate; + CheckBox mChkCertify; + CheckBox mChkSign; + CheckBox mChkEncrypt; + CheckBox mChkAuthenticate; private int mDatePickerResultCount = 0; private DatePickerDialog.OnDateSetListener mExpiryDateSetListener = new DatePickerDialog.OnDateSetListener() { @@ -89,21 +96,13 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mKeyId = (TextView) findViewById(R.id.keyId); mCreationDate = (TextView) findViewById(R.id.creation); mExpiryDateButton = (BootstrapButton) findViewById(R.id.expiry); - //mUsage = (Spinner) findViewById(R.id.usage); - //Choice choices[] = { - // new Choice(Id.choice.usage.sign_only, getResources().getString( - // R.string.choice_sign_only)), - // new Choice(Id.choice.usage.encrypt_only, getResources().getString( - // R.string.choice_encrypt_only)), - // new Choice(Id.choice.usage.sign_and_encrypt, getResources().getString( - // R.string.choice_sign_and_encrypt)), }; - //ArrayAdapter adapter = new ArrayAdapter(getContext(), - // android.R.layout.simple_spinner_item, choices); - //adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - //mUsage.setAdapter(adapter); mDeleteButton = (BootstrapButton) findViewById(R.id.delete); mDeleteButton.setOnClickListener(this); + mChkCertify = (CheckBox) findViewById(R.id.chkCertify); + mChkSign = (CheckBox) findViewById(R.id.chkSign); + mChkEncrypt = (CheckBox) findViewById(R.id.chkEncrypt); + mChkAuthenticate = (CheckBox) findViewById(R.id.chkAuthenticate); setExpiryDate(null); @@ -139,8 +138,10 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { public void setCanEdit(boolean bCanEdit) { if (!bCanEdit) { mDeleteButton.setVisibility(View.INVISIBLE); - //mUsage.setEnabled(false); mExpiryDateButton.setEnabled(false); + mChkSign.setEnabled(false); //certify is always disabled + mChkEncrypt.setEnabled(false); + mChkAuthenticate.setEnabled(false); } } @@ -160,17 +161,26 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { Vector choices = new Vector(); boolean isElGamalKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT); boolean isDSAKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.DSA); - if (!isElGamalKey) { - //choices.add(new Choice(Id.choice.usage.sign_only, getResources().getString( - // R.string.choice_sign_only))); + if (isElGamalKey) { + mChkSign.setVisibility(View.INVISIBLE); + TableLayout table = (TableLayout)findViewById(R.id.table_keylayout); + TableRow row = (TableRow)findViewById(R.id.row_sign); + table.removeView(row); } - if (!mIsMasterKey && !isDSAKey) { - //choices.add(new Choice(Id.choice.usage.encrypt_only, getResources().getString( - // R.string.choice_encrypt_only))); + if (isDSAKey) { + mChkEncrypt.setVisibility(View.INVISIBLE); + TableLayout table = (TableLayout)findViewById(R.id.table_keylayout); + TableRow row = (TableRow)findViewById(R.id.row_encrypt); + table.removeView(row); } - if (!isElGamalKey && !isDSAKey) { - //choices.add(new Choice(Id.choice.usage.sign_and_encrypt, getResources().getString( - // R.string.choice_sign_and_encrypt))); + if (!mIsMasterKey) { + mChkCertify.setVisibility(View.INVISIBLE); + TableLayout table = (TableLayout)findViewById(R.id.table_keylayout); + TableRow row = (TableRow)findViewById(R.id.row_certify); + table.removeView(row); + } else { + TextView mLabelUsage2= (TextView) findViewById(R.id.label_usage2); + mLabelUsage2.setVisibility(View.INVISIBLE); } ArrayAdapter adapter = new ArrayAdapter(getContext(), @@ -180,21 +190,11 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { // Set value in choice dropdown to key int selectId = 0; - if (PgpKeyHelper.isEncryptionKey(key)) { - if (PgpKeyHelper.isSigningKey(key)) { - selectId = Id.choice.usage.sign_and_encrypt; - } else { - selectId = Id.choice.usage.encrypt_only; - } - } else { - // set usage if it is predefined - if (usage != -1) { - selectId = usage; - } else { - selectId = Id.choice.usage.sign_only; - } - - } + if (key.isMasterKey()) + mChkCertify.setChecked(PgpKeyHelper.isCertificationKey(key)); + mChkSign.setChecked(PgpKeyHelper.isSigningKey(key)); + mChkEncrypt.setChecked(PgpKeyHelper.isEncryptionKey(key)); + // TODO: use usage argument? for (int i = 0; i < choices.size(); ++i) { if (choices.get(i).getId() == selectId) { -- cgit v1.2.3 From fd308a671d571b3d8c58d294cda8f6add5832054 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Mon, 3 Feb 2014 00:05:45 +0000 Subject: include authentication keys --- .../keychain/pgp/PgpKeyHelper.java | 30 ++++++++++++++++++++++ .../keychain/ui/widget/KeyEditor.java | 1 + 2 files changed, 31 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index 3fc63cda1..bef41ce64 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -397,6 +397,36 @@ public class PgpKeyHelper { return false; } + public static boolean isAuthenticationKey(PGPSecretKey key) { + return isAuthenticationKey(key.getPublicKey()); + } + + @SuppressWarnings("unchecked") + public static boolean isAuthenticationKey(PGPPublicKey key) { + if (key.getVersion() <= 3) { + return true; + } + + for (PGPSignature sig : new IterableIterator(key.getSignatures())) { + if (key.isMasterKey() && sig.getKeyID() != key.getKeyID()) { + continue; + } + PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets(); + + if (hashed != null && (hashed.getKeyFlags() & KeyFlags.AUTHENTICATION) != 0) { + return true; + } + + PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets(); + + if (unhashed != null && (unhashed.getKeyFlags() & KeyFlags.AUTHENTICATION) != 0) { + return true; + } + } + + return false; + } + public static boolean isCertificationKey(PGPSecretKey key) { return isCertificationKey(key.getPublicKey()); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index f845b53a7..b05963385 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -194,6 +194,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mChkCertify.setChecked(PgpKeyHelper.isCertificationKey(key)); mChkSign.setChecked(PgpKeyHelper.isSigningKey(key)); mChkEncrypt.setChecked(PgpKeyHelper.isEncryptionKey(key)); + mChkAuthenticate.setChecked(PgpKeyHelper.isAuthenticationKey(key)); // TODO: use usage argument? for (int i = 0; i < choices.size(); ++i) { -- cgit v1.2.3 From 089a70fe323ee0628b05709f2f831d6aa32e0281 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Mon, 3 Feb 2014 01:15:29 +0000 Subject: save flags from checkboxes --- .../keychain/pgp/PgpKeyOperation.java | 22 +++++------------- .../keychain/ui/widget/KeyEditor.java | 26 ++++++++++------------ 2 files changed, 18 insertions(+), 30 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 9782d1ac2..d2793a859 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -237,8 +237,8 @@ public class PgpKeyOperation { updateProgress(R.string.progress_preparing_master_key, 10, 100); int usageId = keysUsages.get(0); - boolean canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt); - boolean canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt); + boolean canSign = (usageId & KeyFlags.SIGN_DATA) > 0; + boolean canEncrypt = (usageId & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) > 0; String mainUserId = userIds.get(0); @@ -287,11 +287,7 @@ public class PgpKeyOperation { PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); - int keyFlags = KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA; - if (canEncrypt) { - keyFlags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE; - } - hashedPacketsGen.setKeyFlags(true, keyFlags); + hashedPacketsGen.setKeyFlags(true, usageId); hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS); hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS); @@ -349,14 +345,11 @@ public class PgpKeyOperation { hashedPacketsGen = new PGPSignatureSubpacketGenerator(); unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); - keyFlags = 0; - usageId = keysUsages.get(i); - canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt); - canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt); + canSign = (usageId & KeyFlags.SIGN_DATA) > 0; //todo - separate function for this + canEncrypt = (usageId & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) > 0; if (canSign) { Date todayDate = new Date(); //both sig times the same - keyFlags |= KeyFlags.SIGN_DATA; // cross-certify signing keys hashedPacketsGen.setSignatureCreationTime(false, todayDate); //set outer creation time PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); @@ -371,10 +364,7 @@ public class PgpKeyOperation { subPublicKey); unhashedPacketsGen.setEmbeddedSignature(false, certification); } - if (canEncrypt) { - keyFlags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE; - } - hashedPacketsGen.setKeyFlags(false, keyFlags); + hashedPacketsGen.setKeyFlags(false, usageId); if (keysExpiryDates.get(i) != null) { GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC")); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index b05963385..2bedafc9f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -23,6 +23,7 @@ import java.util.GregorianCalendar; import java.util.TimeZone; import java.util.Vector; +import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPSecretKey; import org.sufficientlysecure.keychain.Id; @@ -183,12 +184,6 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mLabelUsage2.setVisibility(View.INVISIBLE); } - ArrayAdapter adapter = new ArrayAdapter(getContext(), - android.R.layout.simple_spinner_item, choices); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - //mUsage.setAdapter(adapter); - - // Set value in choice dropdown to key int selectId = 0; if (key.isMasterKey()) mChkCertify.setChecked(PgpKeyHelper.isCertificationKey(key)); @@ -197,13 +192,6 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mChkAuthenticate.setChecked(PgpKeyHelper.isAuthenticationKey(key)); // TODO: use usage argument? - for (int i = 0; i < choices.size(); ++i) { - if (choices.get(i).getId() == selectId) { - //mUsage.setSelection(i); - break; - } - } - GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); cal.setTime(PgpKeyHelper.getCreationDate(key)); mCreationDate.setText(DateFormat.getDateInstance().format(cal.getTime())); @@ -250,7 +238,17 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { } public int getUsage() { - return 1; //((Choice) mUsage.getSelectedItem()).getId(); + int result = 0; // TODO: preserve other flags + if (mChkCertify.isChecked()) + result |= KeyFlags.CERTIFY_OTHER; + if (mChkSign.isChecked()) //TODO: fix what happens when we remove sign flag from master - should still be able to certify + result |= KeyFlags.SIGN_DATA; + if (mChkEncrypt.isChecked()) + result |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE; + if (mChkAuthenticate.isChecked()) + result |= KeyFlags.AUTHENTICATION; + + return result; } } -- cgit v1.2.3 From 82b94838c3132064c8011a041466fea04a602b19 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Tue, 4 Feb 2014 00:38:19 +0000 Subject: fix certify keys without sign flag --- .../sufficientlysecure/keychain/provider/ProviderHelper.java | 12 +++++------- .../org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 2 +- .../org/sufficientlysecure/keychain/ui/widget/KeyEditor.java | 1 - 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index a4992163a..12bc33995 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -23,8 +23,6 @@ import java.util.ArrayList; import java.util.Date; import org.spongycastle.bcpg.ArmoredOutputStream; -import org.spongycastle.bcpg.UserAttributePacket; -import org.spongycastle.bcpg.UserAttributeSubpacket; import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKeyRing; @@ -348,7 +346,7 @@ public class ProviderHelper { values.put(Keys.KEY_SIZE, key.getPublicKey().getBitStrength()); values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key) && has_private)); values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key) && has_private)); - values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key)); + values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key) && has_private); values.put(Keys.IS_REVOKED, key.getPublicKey().isRevoked()); values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000); Date expiryDate = PgpKeyHelper.getExpiryDate(key); @@ -441,21 +439,21 @@ public class ProviderHelper { /** * Get empty status of master key of keyring by its row id */ - public static boolean getSecretMasterKeyCanSign(Context context, long keyRingRowId) { + public static boolean getSecretMasterKeyCanCertify(Context context, long keyRingRowId) { Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId)); - return getMasterKeyCanSign(context, queryUri, keyRingRowId); + return getMasterKeyCanCertify(context, queryUri, keyRingRowId); } /** * Private helper method to get master key private empty status of keyring by its row id */ - private static boolean getMasterKeyCanSign(Context context, Uri queryUri, long keyRingRowId) { + private static boolean getMasterKeyCanCertify(Context context, Uri queryUri, long keyRingRowId) { String[] projection = new String[]{ KeyRings.MASTER_KEY_ID, "(SELECT COUNT(sign_keys." + Keys._ID + ") FROM " + Tables.KEYS + " AS sign_keys WHERE sign_keys." + Keys.KEY_RING_ROW_ID + " = " + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID - + " AND sign_keys." + Keys.CAN_SIGN + " = '1' AND " + Keys.IS_MASTER_KEY + + " AND sign_keys." + Keys.CAN_CERTIFY + " = '1' AND " + Keys.IS_MASTER_KEY + " = 1) AS sign",}; ContentResolver cr = context.getContentResolver(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 73426e32d..2c49d4921 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -256,7 +256,7 @@ public class EditKeyActivity extends ActionBarActivity { // get master key id using row id long masterKeyId = ProviderHelper.getSecretMasterKeyId(this, keyRingRowId); - masterCanSign = ProviderHelper.getSecretMasterKeyCanSign(this, keyRingRowId); + masterCanSign = ProviderHelper.getSecretMasterKeyCanCertify(this, keyRingRowId); finallyEdit(masterKeyId, masterCanSign); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 2bedafc9f..2ea044e66 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -59,7 +59,6 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { BootstrapButton mDeleteButton; TextView mAlgorithm; TextView mKeyId; - Spinner mUsage; TextView mCreationDate; BootstrapButton mExpiryDateButton; GregorianCalendar mExpiryDate; -- cgit v1.2.3 From fe3db8f0e68b7490bf98e356474a631dec32530c Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Tue, 4 Feb 2014 01:18:54 +0000 Subject: preserve keys that we don\'t use in the app --- .../keychain/pgp/PgpKeyHelper.java | 27 +++++++++++++++++++--- .../keychain/ui/widget/KeyEditor.java | 20 ++++++++-------- 2 files changed, 33 insertions(+), 14 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index bef41ce64..78d42cbf9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -209,9 +209,8 @@ public class PgpKeyHelper { Calendar calendar = GregorianCalendar.getInstance(); calendar.setTime(creationDate); calendar.add(Calendar.DATE, key.getValidDays()); - Date expiryDate = calendar.getTime(); - return expiryDate; + return calendar.getTime(); } public static Date getExpiryDate(PGPSecretKey key) { @@ -291,6 +290,28 @@ public class PgpKeyHelper { return userId; } + public static int getKeyUsage(PGPSecretKey key) + { + return getKeyUsage(key.getPublicKey()); + } + + @SuppressWarnings("unchecked") + private static int getKeyUsage(PGPPublicKey key) { + int usage = 0; + if (key.getVersion() >= 4) { + for (PGPSignature sig : new IterableIterator(key.getSignatures())) { + if (key.isMasterKey() && sig.getKeyID() != key.getKeyID()) continue; + + PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets(); + if (hashed != null) usage |= hashed.getKeyFlags(); + + PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets(); + if (unhashed != null) usage |= unhashed.getKeyFlags(); + } + } + return usage; + } + @SuppressWarnings("unchecked") public static boolean isEncryptionKey(PGPPublicKey key) { if (!key.isEncryptionKey()) { @@ -440,7 +461,7 @@ public class PgpKeyHelper { } public static String getAlgorithmInfo(int algorithm, int keySize) { - String algorithmStr = null; + String algorithmStr; switch (algorithm) { case PGPPublicKey.RSA_ENCRYPT: diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 2ea044e66..8443895e8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -66,6 +66,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { CheckBox mChkSign; CheckBox mChkEncrypt; CheckBox mChkAuthenticate; + int mUsage; private int mDatePickerResultCount = 0; private DatePickerDialog.OnDateSetListener mExpiryDateSetListener = new DatePickerDialog.OnDateSetListener() { @@ -189,6 +190,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mChkSign.setChecked(PgpKeyHelper.isSigningKey(key)); mChkEncrypt.setChecked(PgpKeyHelper.isEncryptionKey(key)); mChkAuthenticate.setChecked(PgpKeyHelper.isAuthenticationKey(key)); + mUsage = PgpKeyHelper.getKeyUsage(key); // TODO: use usage argument? GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); @@ -237,17 +239,13 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { } public int getUsage() { - int result = 0; // TODO: preserve other flags - if (mChkCertify.isChecked()) - result |= KeyFlags.CERTIFY_OTHER; - if (mChkSign.isChecked()) //TODO: fix what happens when we remove sign flag from master - should still be able to certify - result |= KeyFlags.SIGN_DATA; - if (mChkEncrypt.isChecked()) - result |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE; - if (mChkAuthenticate.isChecked()) - result |= KeyFlags.AUTHENTICATION; - - return result; + mUsage = (mUsage & ~KeyFlags.CERTIFY_OTHER) | (mChkCertify.isChecked() ? KeyFlags.CERTIFY_OTHER : 0); + mUsage = (mUsage & ~KeyFlags.SIGN_DATA) | (mChkSign.isChecked() ? KeyFlags.SIGN_DATA : 0); + mUsage = (mUsage & ~KeyFlags.ENCRYPT_COMMS) | (mChkEncrypt.isChecked() ? KeyFlags.ENCRYPT_COMMS : 0); + mUsage = (mUsage & ~KeyFlags.ENCRYPT_STORAGE) | (mChkEncrypt.isChecked() ? KeyFlags.ENCRYPT_STORAGE : 0); + mUsage = (mUsage & ~KeyFlags.AUTHENTICATION) | (mChkAuthenticate.isChecked() ? KeyFlags.AUTHENTICATION : 0); + + return mUsage; } } -- cgit v1.2.3 From 6d40bc3c0c5e14b77f7de734e57e351eacd6e98c Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Tue, 4 Feb 2014 22:02:53 +0000 Subject: use usage argument if needed --- .../java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java | 8 +++++--- .../org/sufficientlysecure/keychain/ui/widget/SectionView.java | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 8443895e8..2e56c65bc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -146,7 +146,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { } } - public void setValue(PGPSecretKey key, boolean isMasterKey, int usage) { + public void setValue(PGPSecretKey key, boolean isMasterKey, int usage, boolean isNewKey) { mKey = key; mIsMasterKey = isMasterKey; @@ -190,8 +190,10 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mChkSign.setChecked(PgpKeyHelper.isSigningKey(key)); mChkEncrypt.setChecked(PgpKeyHelper.isEncryptionKey(key)); mChkAuthenticate.setChecked(PgpKeyHelper.isAuthenticationKey(key)); - mUsage = PgpKeyHelper.getKeyUsage(key); - // TODO: use usage argument? + if (isNewKey) + mUsage = usage; + else + mUsage = PgpKeyHelper.getKeyUsage(key); GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); cal.setTime(PgpKeyHelper.getCreationDate(key)); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 9d3643914..df69ff60b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -272,7 +272,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor false); view.setEditorListener(this); boolean isMasterKey = (mEditors.getChildCount() == 0); - view.setValue(list.get(i), isMasterKey, usages.get(i)); + view.setValue(list.get(i), isMasterKey, usages.get(i), false); view.setCanEdit(canEdit); mEditors.addView(view); } @@ -344,7 +344,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor KeyEditor view = (KeyEditor) mInflater.inflate(R.layout.edit_key_key_item, mEditors, false); view.setEditorListener(SectionView.this); - view.setValue(newKey, newKey.isMasterKey(), -1); + view.setValue(newKey, newKey.isMasterKey(), -1, true); mEditors.addView(view); SectionView.this.updateEditorsVisible(); } -- cgit v1.2.3 From 8d7cc6755349d06dcd9a2c28dc556c7adb71b8a4 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Wed, 5 Feb 2014 21:04:20 +0000 Subject: save --- .../keychain/ui/EditKeyActivity.java | 13 +++++++- .../keychain/ui/PreferencesKeyServerActivity.java | 7 +++- .../keychain/ui/widget/Editor.java | 4 ++- .../keychain/ui/widget/KeyEditor.java | 37 +++++++++++++++++++--- .../keychain/ui/widget/KeyServerEditor.java | 2 +- .../keychain/ui/widget/SectionView.java | 29 +++++++++++++++-- .../keychain/ui/widget/UserIdEditor.java | 7 +++- 7 files changed, 87 insertions(+), 12 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 2c49d4921..b28ed8922 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -38,9 +38,11 @@ import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; +import org.sufficientlysecure.keychain.ui.widget.Editor; import org.sufficientlysecure.keychain.ui.widget.KeyEditor; import org.sufficientlysecure.keychain.ui.widget.SectionView; import org.sufficientlysecure.keychain.ui.widget.UserIdEditor; +import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; @@ -67,7 +69,7 @@ import android.widget.Toast; import com.beardedhen.androidbootstrap.BootstrapButton; -public class EditKeyActivity extends ActionBarActivity { +public class EditKeyActivity extends ActionBarActivity implements EditorListener { // Actions for internal use only: public static final String ACTION_CREATE_KEY = Constants.INTENT_PREFIX + "CREATE_KEY"; @@ -106,6 +108,15 @@ public class EditKeyActivity extends ActionBarActivity { ExportHelper mExportHelper; + public void onDeleted(Editor e, boolean wasNewItem) + { + } + + public void onEdited() + { + + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java index b5ac739ae..b39b93f52 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java @@ -91,10 +91,15 @@ public class PreferencesKeyServerActivity extends ActionBarActivity implements O } } - public void onDeleted(Editor editor) { + public void onDeleted(Editor editor, boolean wasNewItem) { // nothing to do } + @Override + public void onEdited() { + + } + public void onClick(View v) { KeyServerEditor view = (KeyServerEditor) mInflater.inflate(R.layout.key_server_editor, mEditors, false); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/Editor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/Editor.java index 1cf510d3a..7b21c189d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/Editor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/Editor.java @@ -18,8 +18,10 @@ package org.sufficientlysecure.keychain.ui.widget; public interface Editor { public interface EditorListener { - public void onDeleted(Editor editor); + public void onDeleted(Editor editor, boolean wasNewItem); + public void onEdited(); } public void setEditorListener(EditorListener listener); + public boolean needsSaving(); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 2e56c65bc..c941ea908 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -26,7 +26,6 @@ import java.util.Vector; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPSecretKey; -import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.util.Choice; @@ -39,11 +38,9 @@ import android.util.AttributeSet; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; -import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.DatePicker; import android.widget.LinearLayout; -import android.widget.Spinner; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; @@ -62,11 +59,14 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { TextView mCreationDate; BootstrapButton mExpiryDateButton; GregorianCalendar mExpiryDate; + GregorianCalendar mOriginalExpiryDate = null; CheckBox mChkCertify; CheckBox mChkSign; CheckBox mChkEncrypt; CheckBox mChkAuthenticate; int mUsage; + int mOriginalUsage; + boolean mIsNewKey; private int mDatePickerResultCount = 0; private DatePickerDialog.OnDateSetListener mExpiryDateSetListener = new DatePickerDialog.OnDateSetListener() { @@ -190,10 +190,13 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mChkSign.setChecked(PgpKeyHelper.isSigningKey(key)); mChkEncrypt.setChecked(PgpKeyHelper.isEncryptionKey(key)); mChkAuthenticate.setChecked(PgpKeyHelper.isAuthenticationKey(key)); + mIsNewKey = isNewKey; if (isNewKey) mUsage = usage; - else + else { mUsage = PgpKeyHelper.getKeyUsage(key); + mOriginalUsage = mUsage; + } GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); cal.setTime(PgpKeyHelper.getCreationDate(key)); @@ -205,6 +208,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { } else { cal.setTime(PgpKeyHelper.getExpiryDate(key)); setExpiryDate(cal); + mOriginalExpiryDate = cal; // TODO: ensure time doesn't matter when selecting the same date as before } } @@ -218,7 +222,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { if (v == mDeleteButton) { parent.removeView(this); if (mEditorListener != null) { - mEditorListener.onDeleted(this); + mEditorListener.onDeleted(this, mIsNewKey); } } } @@ -250,4 +254,27 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { return mUsage; } + public boolean needsSaving() + { + if (mIsNewKey) + return true; + + boolean retval = (getUsage() != mOriginalUsage); + + boolean dateChanged; + boolean mOEDNull = (mOriginalExpiryDate == null); + boolean mEDNull = (mExpiryDate == null); + if (mOEDNull != mEDNull) { + dateChanged = true; + } else { + if(mOEDNull) //both null, no change + dateChanged = false; + else + dateChanged = ((mExpiryDate.compareTo(mOriginalExpiryDate)) != 0); + } + retval |= dateChanged; + + return retval; + } + } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java index 01259ccd1..a75aafc11 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java @@ -68,7 +68,7 @@ public class KeyServerEditor extends LinearLayout implements Editor, OnClickList if (v == mDeleteButton) { parent.removeView(this); if (mEditorListener != null) { - mEditorListener.onDeleted(this); + mEditorListener.onDeleted(this, false); } } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index df69ff60b..19926abd3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -50,21 +50,27 @@ import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; -public class SectionView extends LinearLayout implements OnClickListener, EditorListener { +public class SectionView extends LinearLayout implements OnClickListener, EditorListener, Editor { private LayoutInflater mInflater; private BootstrapButton mPlusButton; private ViewGroup mEditors; private TextView mTitle; private int mType = 0; + private EditorListener mEditorListener = null; private Choice mNewKeyAlgorithmChoice; private int mNewKeySize; private boolean canEdit = true; + private boolean oldItemDeleted = false; private ActionBarActivity mActivity; private ProgressDialogFragment mGeneratingDialog; + public void setEditorListener(EditorListener listener) { + mEditorListener = listener; + } + public SectionView(Context context) { super(context); mActivity = (ActionBarActivity) context; @@ -124,15 +130,34 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor } /** {@inheritDoc} */ - public void onDeleted(Editor editor) { + public void onDeleted(Editor editor, boolean wasNewItem) { + oldItemDeleted |= !wasNewItem; this.updateEditorsVisible(); } + @Override + public void onEdited() { + if (mEditorListener != null) { + mEditorListener.onEdited(); + } + } + protected void updateEditorsVisible() { final boolean hasChildren = mEditors.getChildCount() > 0; mEditors.setVisibility(hasChildren ? View.VISIBLE : View.GONE); } + public boolean needsSaving() + { + //check each view for needs saving, take account of deleted items + boolean ret = oldItemDeleted; + for (int i = 0; i < mEditors.getChildCount(); ++i) { + Editor editor = (Editor) mEditors.getChildAt(i); + ret |= editor.needsSaving(); + } + return ret; + } + /** {@inheritDoc} */ public void onClick(View v) { if (canEdit) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index 5428b626e..a56340582 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -175,7 +175,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene boolean wasMainUserId = mIsMainUserId.isChecked(); parent.removeView(this); if (mEditorListener != null) { - mEditorListener.onDeleted(this); + mEditorListener.onDeleted(this, false); } if (wasMainUserId && parent.getChildCount() > 0) { UserIdEditor editor = (UserIdEditor) parent.getChildAt(0); @@ -204,4 +204,9 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene public void setEditorListener(EditorListener listener) { mEditorListener = listener; } + + @Override + public boolean needsSaving() { + return false; + } } -- cgit v1.2.3 From 262425c6ad7cfa6509dc53150e592b3f6fd366c1 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Wed, 5 Feb 2014 21:36:11 +0000 Subject: edit ui knows it it has been changed --- .../keychain/ui/widget/SectionView.java | 5 +---- .../keychain/ui/widget/UserIdEditor.java | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 19926abd3..bf8a3f96b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -273,10 +273,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor UserIdEditor view = (UserIdEditor) mInflater.inflate(R.layout.edit_key_user_id_item, mEditors, false); view.setEditorListener(this); - view.setValue(userId); - if (mEditors.getChildCount() == 0) { - view.setIsMainUserId(true); - } + view.setValue(userId, mEditors.getChildCount() == 0); view.setCanEdit(canEdit); mEditors.addView(view); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index a56340582..4cd1392c2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -38,8 +38,12 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene private BootstrapButton mDeleteButton; private RadioButton mIsMainUserId; private EditText mName; + private String mOriginalName; private EditText mEmail; + private String mOriginalEmail; private EditText mComment; + private String mOriginalComment; + private boolean mOriginallyMainUserID; // see http://www.regular-expressions.info/email.html // RFC 2822 if we omit the syntax using double quotes and square brackets @@ -108,17 +112,22 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene super.onFinishInflate(); } - public void setValue(String userId) { + public void setValue(String userId, boolean isMainID) { mName.setText(""); mComment.setText(""); mEmail.setText(""); + //TODO: update this file for blank email/name? + Pattern withComment = Pattern.compile("^(.*) [(](.*)[)] <(.*)>$"); Matcher matcher = withComment.matcher(userId); if (matcher.matches()) { mName.setText(matcher.group(1)); + mOriginalName = matcher.group(1); mComment.setText(matcher.group(2)); + mOriginalComment = matcher.group(2); mEmail.setText(matcher.group(3)); + mOriginalEmail = matcher.group(3); return; } @@ -126,9 +135,14 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene matcher = withoutComment.matcher(userId); if (matcher.matches()) { mName.setText(matcher.group(1)); + mOriginalName = matcher.group(1); mEmail.setText(matcher.group(2)); + mOriginalEmail = matcher.group(2); + mOriginalComment = ""; return; } + mOriginallyMainUserID = isMainID; + setIsMainUserId(isMainID); } public String getValue() throws NoNameException, NoEmailException, InvalidEmailException { @@ -207,6 +221,10 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene @Override public boolean needsSaving() { - return false; + boolean retval = (mOriginallyMainUserID != isMainUserId()); + retval |= (mOriginalName.equals( ("" + mName.getText()).trim() ) ); + retval |= (mOriginalEmail.equals( ("" + mEmail.getText()).trim() ) ); + retval |= (mOriginalComment.equals( ("" + mComment.getText()).trim() ) ); + return retval; } } -- cgit v1.2.3 From 83514b82c0861b90f33a2b32f9dfc1dd54f2cde4 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Wed, 5 Feb 2014 22:19:07 +0000 Subject: notify of changes --- .../keychain/ui/widget/KeyEditor.java | 24 ++++++++++++++++++++++ .../keychain/ui/widget/UserIdEditor.java | 24 +++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index c941ea908..0ec1bad92 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -39,6 +39,7 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.CheckBox; +import android.widget.CompoundButton; import android.widget.DatePicker; import android.widget.LinearLayout; import android.widget.TableLayout; @@ -68,6 +69,19 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { int mOriginalUsage; boolean mIsNewKey; + private CheckBox.OnCheckedChangeListener mCheckChanged = new CheckBox.OnCheckedChangeListener() + { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) + { + if (mEditorListener != null) { + mEditorListener.onEdited(); + } + } + + } + + private int mDatePickerResultCount = 0; private DatePickerDialog.OnDateSetListener mExpiryDateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { @@ -76,6 +90,9 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("UTC")); date.set(year, monthOfYear, dayOfMonth); setExpiryDate(date); + if (mEditorListener != null) { + mEditorListener.onEdited(); + } } } }; @@ -101,9 +118,13 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mDeleteButton = (BootstrapButton) findViewById(R.id.delete); mDeleteButton.setOnClickListener(this); mChkCertify = (CheckBox) findViewById(R.id.chkCertify); + mChkCertify.setOnCheckedChangeListener(mCheckChanged); mChkSign = (CheckBox) findViewById(R.id.chkSign); + mChkSign.setOnCheckedChangeListener(mCheckChanged); mChkEncrypt = (CheckBox) findViewById(R.id.chkEncrypt); + mChkEncrypt.setOnCheckedChangeListener(mCheckChanged); mChkAuthenticate = (CheckBox) findViewById(R.id.chkAuthenticate); + mChkAuthenticate.setOnCheckedChangeListener(mCheckChanged); setExpiryDate(null); @@ -126,6 +147,9 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { // Note: Ignore results after the first one - android sends multiples. if (mDatePickerResultCount++ == 0) { setExpiryDate(null); + if (mEditorListener != null) { + mEditorListener.onEdited(); + } } } }); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index 4cd1392c2..4b550c580 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -22,6 +22,8 @@ import java.util.regex.Pattern; import org.sufficientlysecure.keychain.R; import android.content.Context; +import android.text.Editable; +import android.text.TextWatcher; import android.util.AttributeSet; import android.view.View; import android.view.View.OnClickListener; @@ -106,6 +108,23 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene mIsMainUserId.setOnClickListener(this); mName = (EditText) findViewById(R.id.name); + mName.addTextChangedListener(new TextWatcher() { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void afterTextChanged(Editable s) + { + if (mEditorListener != null) { + mEditorListener.onEdited(); + } + } + }); mEmail = (EditText) findViewById(R.id.email); mComment = (EditText) findViewById(R.id.comment); @@ -189,7 +208,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene boolean wasMainUserId = mIsMainUserId.isChecked(); parent.removeView(this); if (mEditorListener != null) { - mEditorListener.onDeleted(this, false); + mEditorListener.onDeleted(this, false); //TODO: WAS THIS A NEW ITEM } if (wasMainUserId && parent.getChildCount() > 0) { UserIdEditor editor = (UserIdEditor) parent.getChildAt(0); @@ -204,6 +223,9 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene editor.setIsMainUserId(false); } } + if (mEditorListener != null) { + mEditorListener.onEdited(); + } } } -- cgit v1.2.3 From 603665976a3a75918fb9838361b7194c5def6968 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Feb 2014 09:00:36 +0000 Subject: new Ids need to be saved --- .../java/org/sufficientlysecure/keychain/ui/widget/SectionView.java | 6 ++---- .../org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java | 5 ++++- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index bf8a3f96b..e0d31fa3f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -166,9 +166,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor UserIdEditor view = (UserIdEditor) mInflater.inflate( R.layout.edit_key_user_id_item, mEditors, false); view.setEditorListener(this); - if (mEditors.getChildCount() == 0) { - view.setIsMainUserId(true); - } + view.setValue("", mEditors.getChildCount() == 0, true); mEditors.addView(view); break; } @@ -273,7 +271,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor UserIdEditor view = (UserIdEditor) mInflater.inflate(R.layout.edit_key_user_id_item, mEditors, false); view.setEditorListener(this); - view.setValue(userId, mEditors.getChildCount() == 0); + view.setValue(userId, mEditors.getChildCount() == 0, false); view.setCanEdit(canEdit); mEditors.addView(view); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index 4b550c580..0509e69f2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -46,6 +46,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene private EditText mComment; private String mOriginalComment; private boolean mOriginallyMainUserID; + private boolean mIsNewId; // see http://www.regular-expressions.info/email.html // RFC 2822 if we omit the syntax using double quotes and square brackets @@ -131,10 +132,11 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene super.onFinishInflate(); } - public void setValue(String userId, boolean isMainID) { + public void setValue(String userId, boolean isMainID, boolean isNewId) { mName.setText(""); mComment.setText(""); mEmail.setText(""); + mIsNewId = isNewId; //TODO: update this file for blank email/name? @@ -247,6 +249,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene retval |= (mOriginalName.equals( ("" + mName.getText()).trim() ) ); retval |= (mOriginalEmail.equals( ("" + mEmail.getText()).trim() ) ); retval |= (mOriginalComment.equals( ("" + mComment.getText()).trim() ) ); + retval |= mIsNewId; return retval; } } -- cgit v1.2.3 From a5aae930e5e857005563c21fb2c7ca86d6e235da Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Feb 2014 13:28:59 +0000 Subject: allow blank names and emails --- .../keychain/ui/widget/UserIdEditor.java | 67 ++++++---------------- 1 file changed, 17 insertions(+), 50 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index 0509e69f2..641b710a9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -20,6 +20,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import android.content.Context; import android.text.Editable; @@ -56,14 +57,6 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", Pattern.CASE_INSENSITIVE); - public static class NoNameException extends Exception { - static final long serialVersionUID = 0xf812773343L; - - public NoNameException(String message) { - super(message); - } - } - public void setCanEdit(boolean bCanEdit) { if (!bCanEdit) { mDeleteButton.setVisibility(View.INVISIBLE); @@ -74,14 +67,6 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene } } - public static class NoEmailException extends Exception { - static final long serialVersionUID = 0xf812773344L; - - public NoEmailException(String message) { - super(message); - } - } - public static class InvalidEmailException extends Exception { static final long serialVersionUID = 0xf812773345L; @@ -133,40 +118,31 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene } public void setValue(String userId, boolean isMainID, boolean isNewId) { + mName.setText(""); mComment.setText(""); mEmail.setText(""); mIsNewId = isNewId; - //TODO: update this file for blank email/name? - - Pattern withComment = Pattern.compile("^(.*) [(](.*)[)] <(.*)>$"); - Matcher matcher = withComment.matcher(userId); - if (matcher.matches()) { - mName.setText(matcher.group(1)); - mOriginalName = matcher.group(1); - mComment.setText(matcher.group(2)); - mOriginalComment = matcher.group(2); - mEmail.setText(matcher.group(3)); - mOriginalEmail = matcher.group(3); - return; + String[] result = PgpKeyHelper.splitUserId(userId); + if (result[0] != null) { + mName.setText(result[0]); + mOriginalName = result[0]; } - - Pattern withoutComment = Pattern.compile("^(.*) <(.*)>$"); - matcher = withoutComment.matcher(userId); - if (matcher.matches()) { - mName.setText(matcher.group(1)); - mOriginalName = matcher.group(1); - mEmail.setText(matcher.group(2)); - mOriginalEmail = matcher.group(2); - mOriginalComment = ""; - return; + if (result[1] != null) { + mComment.setText(result[1]); + mOriginalComment = result[1]; + } + if (result[2] != null) { + mEmail.setText(result[2]); + mOriginalEmail = result[2]; } + mOriginallyMainUserID = isMainID; setIsMainUserId(isMainID); } - public String getValue() throws NoNameException, NoEmailException, InvalidEmailException { + public String getValue() throws InvalidEmailException { String name = ("" + mName.getText()).trim(); String email = ("" + mEmail.getText()).trim(); String comment = ("" + mComment.getText()).trim(); @@ -191,16 +167,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene // ok, empty one... return userId; } - - // otherwise make sure that name and email exist - if (name.equals("")) { - throw new NoNameException("need a name"); - } - - if (email.equals("")) { - throw new NoEmailException("need an email"); - } - + //TODO: check gpg accepts an entirely empty ID packet. specs say this is allowed return userId; } @@ -210,7 +177,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene boolean wasMainUserId = mIsMainUserId.isChecked(); parent.removeView(this); if (mEditorListener != null) { - mEditorListener.onDeleted(this, false); //TODO: WAS THIS A NEW ITEM + mEditorListener.onDeleted(this, mIsNewId); } if (wasMainUserId && parent.getChildCount() > 0) { UserIdEditor editor = (UserIdEditor) parent.getChildAt(0); -- cgit v1.2.3 From e7ebbc5ef662ecfe4f43ae203731c6d25cc26e0d Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Feb 2014 13:56:34 +0000 Subject: final link in chain, fix compile --- .../org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 12 ++++++------ .../org/sufficientlysecure/keychain/ui/widget/KeyEditor.java | 3 +-- .../keychain/ui/widget/KeyServerEditor.java | 5 +++++ 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index b28ed8922..d8489ce65 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -96,6 +96,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener private String mNewPassPhrase = null; private String mSavedNewPassPhrase = null; private boolean mIsPassPhraseSet; + private boolean mNeedsSaving; private BootstrapButton mChangePassPhrase; @@ -114,7 +115,9 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public void onEdited() { - + mNeedsSaving = mUserIdsView.needsSaving(); + mNeedsSaving |= mKeysView.needsSaving(); + Toast.makeText(this, "Needs saving: " + Boolean.toString(mNeedsSaving), Toast.LENGTH_LONG).show(); } @Override @@ -437,11 +440,13 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener mUserIdsView.setType(Id.type.user_id); mUserIdsView.setCanEdit(masterCanSign); mUserIdsView.setUserIds(mUserIds); + mUserIdsView.setEditorListener(this); container.addView(mUserIdsView); mKeysView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); mKeysView.setType(Id.type.key); mKeysView.setCanEdit(masterCanSign); mKeysView.setKeys(mKeys, mKeysUsages); + mKeysView.setEditorListener(this); container.addView(mKeysView); updatePassPhraseButtonText(); @@ -597,11 +602,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener String userId = null; try { userId = editor.getValue(); - } catch (UserIdEditor.NoNameException e) { - throw new PgpGeneralException(this.getString(R.string.error_user_id_needs_a_name)); - } catch (UserIdEditor.NoEmailException e) { - throw new PgpGeneralException( - this.getString(R.string.error_user_id_needs_an_email_address)); } catch (UserIdEditor.InvalidEmailException e) { throw new PgpGeneralException(e.getMessage()); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 0ec1bad92..009b0cb10 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -78,8 +78,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mEditorListener.onEdited(); } } - - } + }; private int mDatePickerResultCount = 0; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java index a75aafc11..47238cd56 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java @@ -73,6 +73,11 @@ public class KeyServerEditor extends LinearLayout implements Editor, OnClickList } } + @Override + public boolean needsSaving() { + return false; + } + public void setEditorListener(EditorListener listener) { mEditorListener = listener; } -- cgit v1.2.3 From d6726fe9d6a2efccca394567424342df9a941f2e Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Feb 2014 14:25:09 +0000 Subject: some fixes --- .../keychain/ui/widget/UserIdEditor.java | 47 +++++++++++++--------- 1 file changed, 27 insertions(+), 20 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index 641b710a9..e3747aeb9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -83,6 +83,24 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene super(context, attrs); } + TextWatcher mTextWatcher = new TextWatcher() { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void afterTextChanged(Editable s) + { + if (mEditorListener != null) { + mEditorListener.onEdited(); + } + } + }; + @Override protected void onFinishInflate() { setDrawingCacheEnabled(true); @@ -94,25 +112,11 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene mIsMainUserId.setOnClickListener(this); mName = (EditText) findViewById(R.id.name); - mName.addTextChangedListener(new TextWatcher() { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void afterTextChanged(Editable s) - { - if (mEditorListener != null) { - mEditorListener.onEdited(); - } - } - }); + mName.addTextChangedListener(mTextWatcher); mEmail = (EditText) findViewById(R.id.email); + mEmail.addTextChangedListener(mTextWatcher); mComment = (EditText) findViewById(R.id.comment); + mComment.addTextChangedListener(mTextWatcher); super.onFinishInflate(); } @@ -120,8 +124,11 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene public void setValue(String userId, boolean isMainID, boolean isNewId) { mName.setText(""); + mOriginalName = ""; mComment.setText(""); + mOriginalComment = ""; mEmail.setText(""); + mOriginalEmail = ""; mIsNewId = isNewId; String[] result = PgpKeyHelper.splitUserId(userId); @@ -213,9 +220,9 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene @Override public boolean needsSaving() { boolean retval = (mOriginallyMainUserID != isMainUserId()); - retval |= (mOriginalName.equals( ("" + mName.getText()).trim() ) ); - retval |= (mOriginalEmail.equals( ("" + mEmail.getText()).trim() ) ); - retval |= (mOriginalComment.equals( ("" + mComment.getText()).trim() ) ); + retval |= !(mOriginalName.equals( ("" + mName.getText()).trim() ) ); + retval |= !(mOriginalEmail.equals( ("" + mEmail.getText()).trim() ) ); + retval |= !(mOriginalComment.equals( ("" + mComment.getText()).trim() ) ); retval |= mIsNewId; return retval; } -- cgit v1.2.3 From 53dc044ab4da1e177f4259863cb7fb0266521f6e Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Feb 2014 14:33:29 +0000 Subject: pass message when key added --- .../java/org/sufficientlysecure/keychain/ui/widget/SectionView.java | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index e0d31fa3f..072c04f03 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -168,6 +168,9 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor view.setEditorListener(this); view.setValue("", mEditors.getChildCount() == 0, true); mEditors.addView(view); + if (mEditorListener != null) { + mEditorListener.onEdited(); + } break; } @@ -367,5 +370,8 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor view.setValue(newKey, newKey.isMasterKey(), -1, true); mEditors.addView(view); SectionView.this.updateEditorsVisible(); + if (mEditorListener != null) { + mEditorListener.onEdited(); + } } } -- cgit v1.2.3 From 6dbf48275518b6089d4f4a92d20e460d0a2f96ba Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Feb 2014 15:21:29 +0000 Subject: passphrase changes update need to save --- .../keychain/ui/EditKeyActivity.java | 24 +++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index d8489ce65..b3df52726 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -109,15 +109,22 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener ExportHelper mExportHelper; + public void somethingChanged() + { + mNeedsSaving = mUserIdsView.needsSaving(); + mNeedsSaving |= mKeysView.needsSaving(); + mNeedsSaving |= hasPassphraseChanged(); + Toast.makeText(this, "Needs saving: " + Boolean.toString(mNeedsSaving) + "(" + Boolean.toString(mUserIdsView.needsSaving()) + ", " + Boolean.toString(mKeysView.needsSaving()) + ")", Toast.LENGTH_LONG).show(); + } + public void onDeleted(Editor e, boolean wasNewItem) { + somethingChanged(); } public void onEdited() { - mNeedsSaving = mUserIdsView.needsSaving(); - mNeedsSaving |= mKeysView.needsSaving(); - Toast.makeText(this, "Needs saving: " + Boolean.toString(mNeedsSaving), Toast.LENGTH_LONG).show(); + somethingChanged(); } @Override @@ -400,6 +407,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener .getString(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE); updatePassPhraseButtonText(); + somethingChanged(); } } }; @@ -471,6 +479,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener mNewPassPhrase = mSavedNewPassPhrase; mChangePassPhrase.setVisibility(View.VISIBLE); } + somethingChanged(); } }); } @@ -493,6 +502,15 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } } + public boolean hasPassphraseChanged() + { + if (mNoPassphrase.isChecked()) { + return mIsPassPhraseSet; + } else { + return (mNewPassPhrase != null && !mNewPassPhrase.equals("")); + } + } + private void saveClicked() { long masterKeyId = getMasterKeyId(); try { -- cgit v1.2.3 From d4d6de1bc5c538c17613f5918e70ee0932637915 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Feb 2014 20:07:04 +0000 Subject: select old date doesn't need save --- .../java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 009b0cb10..ba10c7603 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -88,7 +88,11 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { if (mDatePickerResultCount++ == 0) { GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("UTC")); date.set(year, monthOfYear, dayOfMonth); - setExpiryDate(date); + long numDays = (date.getTimeInMillis() / 86400000) - (mOriginalExpiryDate.getTimeInMillis() / 86400000); + if (numDays == 0) + setExpiryDate(mOriginalExpiryDate); + else + setExpiryDate(date); if (mEditorListener != null) { mEditorListener.onEdited(); } @@ -231,7 +235,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { } else { cal.setTime(PgpKeyHelper.getExpiryDate(key)); setExpiryDate(cal); - mOriginalExpiryDate = cal; // TODO: ensure time doesn't matter when selecting the same date as before + mOriginalExpiryDate = cal; } } -- cgit v1.2.3 From aee4ec6d1f5b41d882dea747915af93cd7d84652 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Feb 2014 22:16:41 +0000 Subject: action bar and a small fix --- .../keychain/ui/EditKeyActivity.java | 57 ++++++++++++---------- .../keychain/ui/widget/SectionView.java | 3 ++ .../keychain/ui/widget/UserIdEditor.java | 8 +-- 3 files changed, 38 insertions(+), 30 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index b3df52726..89af2d683 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -55,6 +55,7 @@ import android.os.Handler; import android.os.Message; import android.os.Messenger; import android.support.v7.app.ActionBarActivity; +import android.support.v4.app.ActivityCompat; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -97,6 +98,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener private String mSavedNewPassPhrase = null; private boolean mIsPassPhraseSet; private boolean mNeedsSaving; + private MenuItem mSaveButton; private BootstrapButton mChangePassPhrase; @@ -109,12 +111,19 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener ExportHelper mExportHelper; - public void somethingChanged() + public boolean needsSaving() { mNeedsSaving = mUserIdsView.needsSaving(); mNeedsSaving |= mKeysView.needsSaving(); mNeedsSaving |= hasPassphraseChanged(); - Toast.makeText(this, "Needs saving: " + Boolean.toString(mNeedsSaving) + "(" + Boolean.toString(mUserIdsView.needsSaving()) + ", " + Boolean.toString(mKeysView.needsSaving()) + ")", Toast.LENGTH_LONG).show(); + return mNeedsSaving; + } + + + public void somethingChanged() + { + ActivityCompat.invalidateOptionsMenu(this); + //Toast.makeText(this, "Needs saving: " + Boolean.toString(mNeedsSaving) + "(" + Boolean.toString(mUserIdsView.needsSaving()) + ", " + Boolean.toString(mKeysView.needsSaving()) + ")", Toast.LENGTH_LONG).show(); } public void onDeleted(Editor e, boolean wasNewItem) @@ -133,6 +142,10 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener mExportHelper = new ExportHelper(this); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setIcon(android.R.color.transparent); + getSupportActionBar().setHomeButtonEnabled(true); + mUserIds = new Vector(); mKeys = new Vector(); mKeysUsages = new Vector(); @@ -153,20 +166,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener * @param intent */ private void handleActionCreateKey(Intent intent) { - // Inflate a "Done"/"Cancel" custom action bar - ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_save, - new View.OnClickListener() { - @Override - public void onClick(View v) { - saveClicked(); - } - }, R.string.btn_do_not_save, new View.OnClickListener() { - @Override - public void onClick(View v) { - cancelClicked(); - } - }); - Bundle extras = intent.getExtras(); mCurrentPassPhrase = ""; @@ -255,15 +254,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener * @param intent */ private void handleActionEditKey(Intent intent) { - // Inflate a "Done"/"Cancel" custom action bar - ActionBarHelper.setDoneView(getSupportActionBar(), R.string.btn_save, - new View.OnClickListener() { - @Override - public void onClick(View v) { - saveClicked(); - } - }); - mDataUri = intent.getData(); if (mDataUri == null) { Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!"); @@ -325,12 +315,17 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.key_edit, menu); + mSaveButton = (MenuItem) menu.findItem(R.id.menu_key_edit_save); + mSaveButton.setEnabled(needsSaving()); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { + case android.R.id.home: + cancelClicked(); + return true; case R.id.menu_key_edit_cancel: cancelClicked(); return true; @@ -353,6 +348,9 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener mExportHelper.deleteKey(mDataUri, Id.type.secret_key, returnHandler); return true; } + case R.id.menu_key_edit_save: + saveClicked(); + return true; } return super.onOptionsItemSelected(item); } @@ -373,8 +371,15 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener Toast.makeText(this, R.string.error_no_secret_key_found, Toast.LENGTH_LONG).show(); } if (masterKey != null) { + boolean isSet = false; for (String userId : new IterableIterator(masterKey.getUserIDs())) { Log.d(Constants.TAG, "Added userId " + userId); + if (!isSet) { + isSet = true; + String[] parts = PgpKeyHelper.splitUserId(userId); + if (parts[0] != null) + setTitle(parts[0]); + } mUserIds.add(userId); } } @@ -465,7 +470,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } }); - // disable passphrase when no passphrase checkobox is checked! + // disable passphrase when no passphrase checkbox is checked! mNoPassphrase.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 072c04f03..21ebff102 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -133,6 +133,9 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor public void onDeleted(Editor editor, boolean wasNewItem) { oldItemDeleted |= !wasNewItem; this.updateEditorsVisible(); + if (mEditorListener != null) { + mEditorListener.onEdited(); + } } @Override diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index e3747aeb9..b499a429a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -137,12 +137,12 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene mOriginalName = result[0]; } if (result[1] != null) { - mComment.setText(result[1]); - mOriginalComment = result[1]; + mEmail.setText(result[1]); + mOriginalEmail = result[1]; } if (result[2] != null) { - mEmail.setText(result[2]); - mOriginalEmail = result[2]; + mComment.setText(result[2]); + mOriginalComment = result[2]; } mOriginallyMainUserID = isMainID; -- cgit v1.2.3 From fd33a6764567bfd02c1af228161501078ca8030a Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Feb 2014 22:35:27 +0000 Subject: ask for save --- .../keychain/ui/EditKeyActivity.java | 33 ++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 89af2d683..49713db71 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -46,8 +46,10 @@ import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; +import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -604,8 +606,35 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } private void cancelClicked() { - setResult(RESULT_CANCELED); - finish(); + if (mNeedsSaving && masterCanSign) { //ask if we want to save + AlertDialog.Builder alert = new AlertDialog.Builder( + EditKeyActivity.this); + + alert.setIcon(android.R.drawable.ic_dialog_alert); + alert.setTitle(R.string.warning); + alert.setMessage(EditKeyActivity.this.getString(R.string.ask_save_changed_key)); + + alert.setPositiveButton(EditKeyActivity.this.getString(android.R.string.yes), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.dismiss(); + saveClicked(); + } + }); + alert.setNegativeButton(this.getString(android.R.string.no), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.dismiss(); + setResult(RESULT_CANCELED); + finish(); + } + }); + alert.setCancelable(false); + alert.create().show(); + } else { + setResult(RESULT_CANCELED); + finish(); + } } /** -- cgit v1.2.3 From 899fadb9169e93105f633c0925835cce9c413b24 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Feb 2014 22:43:59 +0000 Subject: can change passwords --- .../main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 49713db71..694e52f71 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -606,7 +606,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } private void cancelClicked() { - if (mNeedsSaving && masterCanSign) { //ask if we want to save + if (mNeedsSaving) { //ask if we want to save AlertDialog.Builder alert = new AlertDialog.Builder( EditKeyActivity.this); -- cgit v1.2.3 From 8d1047d05c3a0e1e1310fb1a47dc6d4f80b2c0f4 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Feb 2014 22:52:22 +0000 Subject: fix a crash --- .../org/sufficientlysecure/keychain/ui/widget/KeyEditor.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index ba10c7603..fa220313c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -88,11 +88,15 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { if (mDatePickerResultCount++ == 0) { GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("UTC")); date.set(year, monthOfYear, dayOfMonth); - long numDays = (date.getTimeInMillis() / 86400000) - (mOriginalExpiryDate.getTimeInMillis() / 86400000); - if (numDays == 0) - setExpiryDate(mOriginalExpiryDate); - else + if (mOriginalExpiryDate != null) { + long numDays = (date.getTimeInMillis() / 86400000) - (mOriginalExpiryDate.getTimeInMillis() / 86400000); + if (numDays == 0) + setExpiryDate(mOriginalExpiryDate); + else + setExpiryDate(date); + } else { setExpiryDate(date); + } if (mEditorListener != null) { mEditorListener.onEdited(); } -- cgit v1.2.3 From cd2b493ea8d25796bf666b46597e6b6bd416f64b Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 8 Feb 2014 12:12:17 +0000 Subject: small extra check --- .../keychain/ui/EditKeyActivity.java | 38 ++++++++++++---------- 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 694e52f71..d53a1f836 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -326,7 +326,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: - cancelClicked(); + cancelClicked(); //TODO: why isn't this triggered on my tablet - one of many ui problems I've had with this device. A code compatibility issue or a Samsung fail? return true; case R.id.menu_key_edit_cancel: cancelClicked(); @@ -520,25 +520,27 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener private void saveClicked() { long masterKeyId = getMasterKeyId(); - try { - if (!isPassphraseSet()) { - throw new PgpGeneralException(this.getString(R.string.set_a_passphrase)); - } + if (needsSaving()) { //make sure, as some versions don't support invalidateOptionsMenu + try { + if (!isPassphraseSet()) { + throw new PgpGeneralException(this.getString(R.string.set_a_passphrase)); + } - String passphrase = null; - if (mIsPassPhraseSet) - passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId); - else - passphrase = ""; - if (passphrase == null) { - showPassphraseDialog(masterKeyId, masterCanSign); - } else { - mCurrentPassPhrase = passphrase; - finallySaveClicked(); + String passphrase = null; + if (mIsPassPhraseSet) + passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId); + else + passphrase = ""; + if (passphrase == null) { + showPassphraseDialog(masterKeyId, masterCanSign); + } else { + mCurrentPassPhrase = passphrase; + finallySaveClicked(); + } + } catch (PgpGeneralException e) { + Toast.makeText(this, getString(R.string.error_message, e.getMessage()), + Toast.LENGTH_SHORT).show(); } - } catch (PgpGeneralException e) { - //Toast.makeText(this, getString(R.string.error_message, e.getMessage()), - // Toast.LENGTH_SHORT).show(); } } -- cgit v1.2.3 From b74ed4643453cd089ec885bb3f56169629f8cacf Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 8 Feb 2014 15:35:44 +0000 Subject: disable export if unsaved --- .../java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index d53a1f836..66f23e22e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -332,8 +332,12 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener cancelClicked(); return true; case R.id.menu_key_edit_export_file: - mExportHelper.showExportKeysDialog(mDataUri, Id.type.secret_key, Constants.path.APP_DIR - + "/secexport.asc"); + if (needsSaving()) { + Toast.makeText(this, R.string.error_save_first, Toast.LENGTH_LONG).show(); + } else { + mExportHelper.showExportKeysDialog(mDataUri, Id.type.secret_key, Constants.path.APP_DIR + + "/secexport.asc"); + } return true; case R.id.menu_key_edit_delete: { // Message is received after key is deleted -- cgit v1.2.3 From 44ee7137632c2fd8e6d97a8f05a213467ecf1dc6 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 8 Feb 2014 15:51:11 +0000 Subject: fix create keyring crash --- .../sufficientlysecure/keychain/ui/EditKeyActivity.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 66f23e22e..802d29a44 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -115,8 +115,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public boolean needsSaving() { - mNeedsSaving = mUserIdsView.needsSaving(); - mNeedsSaving |= mKeysView.needsSaving(); + mNeedsSaving = (mUserIdsView == null) ? false : mUserIdsView.needsSaving(); + mNeedsSaving |= (mKeysView == null) ? false : mKeysView.needsSaving(); mNeedsSaving |= hasPassphraseChanged(); return mNeedsSaving; } @@ -515,10 +515,14 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public boolean hasPassphraseChanged() { - if (mNoPassphrase.isChecked()) { - return mIsPassPhraseSet; - } else { - return (mNewPassPhrase != null && !mNewPassPhrase.equals("")); + if (mNoPassphrase != null) { + if (mNoPassphrase.isChecked()) { + return mIsPassPhraseSet; + } else { + return (mNewPassPhrase != null && !mNewPassPhrase.equals("")); + } + }else { + return false; } } -- cgit v1.2.3 From 5def251e62d383f023c62fea1734977e11b0fa27 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 8 Feb 2014 15:59:44 +0000 Subject: keep track of brand new keys, they need saving --- .../java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 802d29a44..9ddfadef1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -100,6 +100,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener private String mSavedNewPassPhrase = null; private boolean mIsPassPhraseSet; private boolean mNeedsSaving; + private boolean mIsBrandNewKeyring = false; private MenuItem mSaveButton; private BootstrapButton mChangePassPhrase; @@ -118,6 +119,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener mNeedsSaving = (mUserIdsView == null) ? false : mUserIdsView.needsSaving(); mNeedsSaving |= (mKeysView == null) ? false : mKeysView.needsSaving(); mNeedsSaving |= hasPassphraseChanged(); + mNeedsSaving |= mIsBrandNewKeyring; return mNeedsSaving; } @@ -171,6 +173,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener Bundle extras = intent.getExtras(); mCurrentPassPhrase = ""; + mIsBrandNewKeyring = true; if (extras != null) { // if userId is given, prefill the fields @@ -616,7 +619,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } private void cancelClicked() { - if (mNeedsSaving) { //ask if we want to save + if (needsSaving()) { //ask if we want to save AlertDialog.Builder alert = new AlertDialog.Builder( EditKeyActivity.this); -- cgit v1.2.3 From 33f41e66a0a39ab7b8eb48c1055ba16ce8d784f5 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 8 Feb 2014 16:18:30 +0000 Subject: consistent ui --- .../sufficientlysecure/keychain/ui/EditKeyActivity.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 9ddfadef1..a0c2871ae 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -306,22 +306,19 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } } - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - // show menu only on edit - if (mDataUri != null) { - return super.onPrepareOptionsMenu(menu); - } else { - return false; - } - } - @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.key_edit, menu); mSaveButton = (MenuItem) menu.findItem(R.id.menu_key_edit_save); mSaveButton.setEnabled(needsSaving()); + //totally get rid of some actions for new keys + if (mDataUri == null) { + MenuItem mButton = (MenuItem) menu.findItem(R.id.menu_key_edit_export_file); + mButton.setVisible(false); + mButton = (MenuItem) menu.findItem(R.id.menu_key_edit_delete); + mButton.setVisible(false); + } return true; } -- cgit v1.2.3 From adc6a3ea64c00f35e881e856d2877c2ea88c7e51 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 8 Feb 2014 16:33:37 +0000 Subject: some AS Inspect Code fixes --- .../keychain/ui/EditKeyActivity.java | 33 ++++++++++------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index a0c2871ae..d12a5479d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -26,7 +26,6 @@ import org.spongycastle.openpgp.PGPSecretKeyRing; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.helper.ExportHelper; import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; @@ -218,10 +217,10 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { // get new key from data bundle returned from service Bundle data = message.getData(); - PGPSecretKey masterKey = (PGPSecretKey) PgpConversionHelper + PGPSecretKey masterKey = PgpConversionHelper .BytesToPGPSecretKey(data .getByteArray(KeychainIntentService.RESULT_NEW_KEY)); - PGPSecretKey subKey = (PGPSecretKey) PgpConversionHelper + PGPSecretKey subKey = PgpConversionHelper .BytesToPGPSecretKey(data .getByteArray(KeychainIntentService.RESULT_NEW_KEY2)); @@ -235,7 +234,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener buildLayout(); } - }; + } }; // Create a new Messenger for the communication back @@ -263,7 +262,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener if (mDataUri == null) { Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!"); finish(); - return; } else { Log.d(Constants.TAG, "uri: " + mDataUri); @@ -273,19 +271,18 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener long masterKeyId = ProviderHelper.getSecretMasterKeyId(this, keyRingRowId); masterCanSign = ProviderHelper.getSecretMasterKeyCanCertify(this, keyRingRowId); - finallyEdit(masterKeyId, masterCanSign); + finallyEdit(masterKeyId); } } - private void showPassphraseDialog(final long masterKeyId, final boolean masterCanSign) { + private void showPassphraseDialog(final long masterKeyId) { // Message is received after passphrase is cached Handler returnHandler = new Handler() { @Override public void handleMessage(Message message) { if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - String passPhrase = PassphraseCacheService.getCachedPassphrase( + mCurrentPassPhrase = PassphraseCacheService.getCachedPassphrase( EditKeyActivity.this, masterKeyId); - mCurrentPassPhrase = passPhrase; finallySaveClicked(); } } @@ -310,13 +307,13 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.key_edit, menu); - mSaveButton = (MenuItem) menu.findItem(R.id.menu_key_edit_save); + mSaveButton = menu.findItem(R.id.menu_key_edit_save); mSaveButton.setEnabled(needsSaving()); //totally get rid of some actions for new keys if (mDataUri == null) { - MenuItem mButton = (MenuItem) menu.findItem(R.id.menu_key_edit_export_file); + MenuItem mButton = menu.findItem(R.id.menu_key_edit_export_file); mButton.setVisible(false); - mButton = (MenuItem) menu.findItem(R.id.menu_key_edit_delete); + mButton = menu.findItem(R.id.menu_key_edit_delete); mButton.setVisible(false); } return true; @@ -362,7 +359,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } @SuppressWarnings("unchecked") - private void finallyEdit(final long masterKeyId, final boolean masterCanSign) { + private void finallyEdit(final long masterKeyId) { if (masterKeyId != 0) { PGPSecretKey masterKey = null; mKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, masterKeyId); @@ -427,7 +424,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener Messenger messenger = new Messenger(returnHandler); // set title based on isPassphraseSet() - int title = -1; + int title; if (isPassphraseSet()) { title = R.string.title_change_pass_phrase; } else { @@ -534,13 +531,13 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener throw new PgpGeneralException(this.getString(R.string.set_a_passphrase)); } - String passphrase = null; + String passphrase; if (mIsPassPhraseSet) passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId); else passphrase = ""; if (passphrase == null) { - showPassphraseDialog(masterKeyId, masterCanSign); + showPassphraseDialog(masterKeyId); } else { mCurrentPassPhrase = passphrase; finallySaveClicked(); @@ -598,7 +595,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener setResult(RESULT_OK, data); finish(); } - }; + } }; // Create a new Messenger for the communication back @@ -661,7 +658,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener boolean gotMainUserId = false; for (int i = 0; i < userIdEditors.getChildCount(); ++i) { UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i); - String userId = null; + String userId; try { userId = editor.getValue(); } catch (UserIdEditor.InvalidEmailException e) { -- cgit v1.2.3 From 75640934a080d21113f501ed604b85de3eab6b51 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 8 Feb 2014 21:04:38 +0000 Subject: saving fixes --- .../keychain/ui/EditKeyActivity.java | 26 +++++++++++----------- .../keychain/ui/widget/KeyEditor.java | 20 +++++++++++------ .../keychain/ui/widget/SectionView.java | 10 ++++++--- 3 files changed, 33 insertions(+), 23 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index d12a5479d..132141bc5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.Vector; +import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; import org.sufficientlysecure.keychain.Constants; @@ -224,15 +225,17 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener .BytesToPGPSecretKey(data .getByteArray(KeychainIntentService.RESULT_NEW_KEY2)); + //We must set the key flags here as they are not set when we make the + //key pair. Because we are not generating hashed packets there... // add master key mKeys.add(masterKey); - mKeysUsages.add(Id.choice.usage.sign_only); //TODO: get from key flags + mKeysUsages.add(KeyFlags.CERTIFY_OTHER); // add sub key mKeys.add(subKey); - mKeysUsages.add(Id.choice.usage.encrypt_only); //TODO: get from key flags + mKeysUsages.add(KeyFlags.ENCRYPT_COMMS + KeyFlags.ENCRYPT_STORAGE); - buildLayout(); + buildLayout(true); } } }; @@ -248,7 +251,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } } } else { - buildLayout(); + buildLayout(false); } } @@ -390,7 +393,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener mCurrentPassPhrase = ""; - buildLayout(); + buildLayout(false); mIsPassPhraseSet = PassphraseCacheService.hasPassphrase(this, masterKeyId); if (!mIsPassPhraseSet) { // check "no passphrase" checkbox and remove button @@ -440,8 +443,9 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener /** * Build layout based on mUserId, mKeys and mKeysUsages Vectors. It creates Views for every user * id and key. + * @param newKeys */ - private void buildLayout() { + private void buildLayout(boolean newKeys) { setContentView(R.layout.edit_key_activity); // find views @@ -461,7 +465,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener mKeysView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); mKeysView.setType(Id.type.key); mKeysView.setCanEdit(masterCanSign); - mKeysView.setKeys(mKeys, mKeysUsages); + mKeysView.setKeys(mKeys, mKeysUsages, newKeys); mKeysView.setEditorListener(this); container.addView(mKeysView); @@ -607,8 +611,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener // start service with intent startService(intent); } catch (PgpGeneralException e) { - //Toast.makeText(this, getString(R.string.error_message, e.getMessage()), - // Toast.LENGTH_SHORT).show(); + Toast.makeText(this, getString(R.string.error_message, e.getMessage()), + Toast.LENGTH_SHORT).show(); } } @@ -665,10 +669,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener throw new PgpGeneralException(e.getMessage()); } - if (userId.equals("")) { - continue; - } - if (editor.isMainUserId()) { userIds.add(0, userId); gotMainUserId = true; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index fa220313c..5ce5d89d7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -24,6 +24,7 @@ import java.util.TimeZone; import java.util.Vector; import org.spongycastle.bcpg.sig.KeyFlags; +import org.spongycastle.openpgp.PGPKeyFlags; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPSecretKey; import org.sufficientlysecure.keychain.R; @@ -216,17 +217,22 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { } int selectId = 0; - if (key.isMasterKey()) - mChkCertify.setChecked(PgpKeyHelper.isCertificationKey(key)); - mChkSign.setChecked(PgpKeyHelper.isSigningKey(key)); - mChkEncrypt.setChecked(PgpKeyHelper.isEncryptionKey(key)); - mChkAuthenticate.setChecked(PgpKeyHelper.isAuthenticationKey(key)); mIsNewKey = isNewKey; - if (isNewKey) + if (isNewKey) { mUsage = usage; - else { + mChkCertify.setChecked((usage &= KeyFlags.CERTIFY_OTHER) == KeyFlags.CERTIFY_OTHER); + mChkSign.setChecked((usage &= KeyFlags.SIGN_DATA) == KeyFlags.SIGN_DATA); + mChkEncrypt.setChecked(((usage &= KeyFlags.ENCRYPT_COMMS) == KeyFlags.ENCRYPT_COMMS) || + ((usage &= KeyFlags.ENCRYPT_STORAGE) == KeyFlags.ENCRYPT_STORAGE)); + mChkAuthenticate.setChecked((usage &= KeyFlags.AUTHENTICATION) == KeyFlags.AUTHENTICATION); + } else { mUsage = PgpKeyHelper.getKeyUsage(key); mOriginalUsage = mUsage; + if (key.isMasterKey()) + mChkCertify.setChecked(PgpKeyHelper.isCertificationKey(key)); + mChkSign.setChecked(PgpKeyHelper.isSigningKey(key)); + mChkEncrypt.setChecked(PgpKeyHelper.isEncryptionKey(key)); + mChkAuthenticate.setChecked(PgpKeyHelper.isAuthenticationKey(key)); } GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 21ebff102..315a8faba 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui.widget; import java.util.Vector; +import org.spongycastle.openpgp.PGPKeyFlags; import org.spongycastle.openpgp.PGPSecretKey; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; @@ -285,7 +286,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor this.updateEditorsVisible(); } - public void setKeys(Vector list, Vector usages) { + public void setKeys(Vector list, Vector usages, boolean newKeys) { if (mType != Id.type.key) { return; } @@ -298,7 +299,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor false); view.setEditorListener(this); boolean isMasterKey = (mEditors.getChildCount() == 0); - view.setValue(list.get(i), isMasterKey, usages.get(i), false); + view.setValue(list.get(i), isMasterKey, usages.get(i), newKeys); view.setCanEdit(canEdit); mEditors.addView(view); } @@ -370,7 +371,10 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor KeyEditor view = (KeyEditor) mInflater.inflate(R.layout.edit_key_key_item, mEditors, false); view.setEditorListener(SectionView.this); - view.setValue(newKey, newKey.isMasterKey(), -1, true); + int usage = 0; + if (mEditors.getChildCount() == 0) + usage = PGPKeyFlags.CAN_CERTIFY; + view.setValue(newKey, newKey.isMasterKey(), usage, true); mEditors.addView(view); SectionView.this.updateEditorsVisible(); if (mEditorListener != null) { -- cgit v1.2.3 From 5bd0a2ebc8d4738d53d5ba3e112069ca6a0d049a Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 8 Feb 2014 21:38:56 +0000 Subject: fix Android Studio analysis issues --- .../keychain/pgp/PgpKeyOperation.java | 54 +++++++--------------- 1 file changed, 17 insertions(+), 37 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index d2793a859..7ab5df613 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -23,6 +23,7 @@ import java.security.InvalidAlgorithmParameterException; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; +import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.util.ArrayList; @@ -56,6 +57,7 @@ import org.spongycastle.openpgp.operator.PGPContentSignerBuilder; import org.spongycastle.openpgp.operator.PGPDigestCalculator; import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair; import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; @@ -71,8 +73,8 @@ import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; import android.content.Context; public class PgpKeyOperation { - private Context mContext; - private ProgressDialogUpdater mProgress; + private final Context mContext; + private final ProgressDialogUpdater mProgress; private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[] { SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, @@ -90,34 +92,18 @@ public class PgpKeyOperation { this.mProgress = progress; } - public void updateProgress(int message, int current, int total) { + void updateProgress(int message, int current, int total) { if (mProgress != null) { mProgress.setProgress(message, current, total); } } - public void updateProgress(int current, int total) { + void updateProgress(int current, int total) { if (mProgress != null) { mProgress.setProgress(current, total); } } - /** - * Creates new secret key. - * - * @param algorithmChoice - * @param keySize - * @param passPhrase - * @param isMasterKey - * @return - * @throws NoSuchAlgorithmException - * @throws PGPException - * @throws NoSuchProviderException - * @throws PgpGeneralException - * @throws InvalidAlgorithmParameterException - */ - - // TODO: key flags? public PGPSecretKey createKey(int algorithmChoice, int keySize, String passPhrase, boolean isMasterKey) throws NoSuchAlgorithmException, PGPException, NoSuchProviderException, PgpGeneralException, InvalidAlgorithmParameterException { @@ -130,8 +116,8 @@ public class PgpKeyOperation { passPhrase = ""; } - int algorithm = 0; - KeyPairGenerator keyGen = null; + int algorithm; + KeyPairGenerator keyGen; switch (algorithmChoice) { case Id.choice.algorithm.dsa: { @@ -183,15 +169,13 @@ public class PgpKeyOperation { PGPEncryptedData.CAST5, sha1Calc) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passPhrase.toCharArray()); - PGPSecretKey secKey = new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(), + return new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(), sha1Calc, isMasterKey, keyEncryptor); - return secKey; } public void changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassPhrase, - String newPassPhrase) throws IOException, PGPException, PGPException, - NoSuchProviderException { + String newPassPhrase) throws IOException, PGPException { updateProgress(R.string.progress_building_key, 0, 100); if (oldPassPhrase == null) { @@ -219,9 +203,8 @@ public class PgpKeyOperation { public void buildSecretKey(ArrayList userIds, ArrayList keys, ArrayList keysUsages, ArrayList keysExpiryDates, - long masterKeyId, String oldPassPhrase, - String newPassPhrase) throws PgpGeneralException, NoSuchProviderException, - PGPException, NoSuchAlgorithmException, SignatureException, IOException { + String oldPassPhrase, String newPassPhrase) throws PgpGeneralException, + PGPException, SignatureException, IOException { Log.d(Constants.TAG, "userIds: " + userIds.toString()); @@ -237,17 +220,16 @@ public class PgpKeyOperation { updateProgress(R.string.progress_preparing_master_key, 10, 100); int usageId = keysUsages.get(0); - boolean canSign = (usageId & KeyFlags.SIGN_DATA) > 0; - boolean canEncrypt = (usageId & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) > 0; - + boolean canSign; String mainUserId = userIds.get(0); PGPSecretKey masterKey = keys.get(0); // this removes all userIds and certifications previously attached to the masterPublicKey PGPPublicKey tmpKey = masterKey.getPublicKey(); - PGPPublicKey masterPublicKey = new PGPPublicKey(tmpKey.getAlgorithm(), - tmpKey.getKey(new BouncyCastleProvider()), tmpKey.getCreationTime()); + PublicKey tmpPuK = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()).getPublicKey(tmpKey); + PGPPublicKey masterPublicKey = new JcaPGPKeyConverter().getPGPPublicKey(tmpKey.getAlgorithm(), + tmpPuK, tmpKey.getCreationTime()); // already done by code above: // PGPPublicKey masterPublicKey = masterKey.getPublicKey(); @@ -347,7 +329,6 @@ public class PgpKeyOperation { usageId = keysUsages.get(i); canSign = (usageId & KeyFlags.SIGN_DATA) > 0; //todo - separate function for this - canEncrypt = (usageId & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) > 0; if (canSign) { Date todayDate = new Date(); //both sig times the same // cross-certify signing keys @@ -396,8 +377,7 @@ public class PgpKeyOperation { } public PGPPublicKeyRing signKey(long masterKeyId, long pubKeyId, String passphrase) - throws PgpGeneralException, NoSuchAlgorithmException, NoSuchProviderException, - PGPException, SignatureException { + throws PgpGeneralException, PGPException, SignatureException { if (passphrase == null) { throw new PgpGeneralException("Unable to obtain passphrase"); } else { -- cgit v1.2.3 From e150004e32d4f4278950dc2b24a9cf70885c468f Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 8 Feb 2014 21:42:04 +0000 Subject: should have used refactor... --- .../org/sufficientlysecure/keychain/service/KeychainIntentService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 657d40a5a..a31ddc53e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -542,7 +542,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial ProviderHelper.getPGPSecretKeyRingByKeyId(this, masterKeyId), oldPassPhrase, newPassPhrase); } else { - keyOperations.buildSecretKey(userIds, keys, keysUsages, keysExpiryDates, masterKeyId, + keyOperations.buildSecretKey(userIds, keys, keysUsages, keysExpiryDates, oldPassPhrase, newPassPhrase); } PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassPhrase); -- cgit v1.2.3 From 076a7ec4a16a6db5df0bbe5490d44cbd514f10c1 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 13 Feb 2014 22:05:36 +0000 Subject: save work, this code doesn't work... --- .../keychain/pgp/PgpKeyOperation.java | 34 ++++++++++------------ .../keychain/service/KeychainIntentService.java | 11 +++++-- .../keychain/ui/EditKeyActivity.java | 15 ++++++++++ .../keychain/ui/widget/SectionView.java | 19 ++++++++++++ 4 files changed, 58 insertions(+), 21 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 7ab5df613..505d3ba55 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -23,7 +23,6 @@ import java.security.InvalidAlgorithmParameterException; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; -import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.util.ArrayList; @@ -35,7 +34,6 @@ import org.spongycastle.bcpg.CompressionAlgorithmTags; import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; import org.spongycastle.bcpg.sig.KeyFlags; -import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.jce.spec.ElGamalParameterSpec; import org.spongycastle.openpgp.PGPEncryptedData; import org.spongycastle.openpgp.PGPException; @@ -57,7 +55,6 @@ import org.spongycastle.openpgp.operator.PGPContentSignerBuilder; import org.spongycastle.openpgp.operator.PGPDigestCalculator; import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair; import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; @@ -201,9 +198,7 @@ public class PgpKeyOperation { } - public void buildSecretKey(ArrayList userIds, ArrayList keys, - ArrayList keysUsages, ArrayList keysExpiryDates, - String oldPassPhrase, String newPassPhrase) throws PgpGeneralException, + public void buildSecretKey(ArrayList userIds, ArrayList OriginalIDs, ArrayList deletedIDs, ArrayList keys, boolean[] modded_keys, String newPassPhrase, ArrayList keysExpiryDates, String oldPassPhrase, ArrayList keysUsages) throws PgpGeneralException, PGPException, SignatureException, IOException { Log.d(Constants.TAG, "userIds: " + userIds.toString()); @@ -226,10 +221,7 @@ public class PgpKeyOperation { PGPSecretKey masterKey = keys.get(0); // this removes all userIds and certifications previously attached to the masterPublicKey - PGPPublicKey tmpKey = masterKey.getPublicKey(); - PublicKey tmpPuK = new JcaPGPKeyConverter().setProvider(new BouncyCastleProvider()).getPublicKey(tmpKey); - PGPPublicKey masterPublicKey = new JcaPGPKeyConverter().getPGPPublicKey(tmpKey.getAlgorithm(), - tmpPuK, tmpKey.getCreationTime()); + PGPPublicKey masterPublicKey = masterKey.getPublicKey(); // already done by code above: // PGPPublicKey masterPublicKey = masterKey.getPublicKey(); @@ -243,6 +235,8 @@ public class PgpKeyOperation { // masterPublicKey = masterPublicKeyRmCert; // } + + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassPhrase.toCharArray()); PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor); @@ -250,18 +244,22 @@ public class PgpKeyOperation { updateProgress(R.string.progress_certifying_master_key, 20, 100); // TODO: if we are editing a key, keep old certs, don't remake certs we don't have to. - + int user_id_index = 0; for (String userId : userIds) { - PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); + if (OriginalIDs[user_id_index]) { + PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( + masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); - sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); + sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); - PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); + PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); - masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); + masterPublicKey = PGPPublicKey.removeCertification(); + masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); + } + user_id_index++; } PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index a31ddc53e..4cace2658 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -54,7 +54,6 @@ import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; import org.sufficientlysecure.keychain.util.HkpKeyServer; import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.PositionAwareInputStream; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; import android.app.IntentService; @@ -135,6 +134,9 @@ public class KeychainIntentService extends IntentService implements ProgressDial public static final String SAVE_KEYRING_KEYS_EXPIRY_DATES = "keys_expiry_dates"; public static final String SAVE_KEYRING_MASTER_KEY_ID = "master_key_id"; public static final String SAVE_KEYRING_CAN_SIGN = "can_sign"; + public static final String SAVE_KEYRING_ORIGINAL_IDS = "original_ids"; + public static final String SAVE_KEYRING_DELETED_IDS = "deleted_ids"; + public static final String SAVE_KEYRING_MODDED_KEYS = "modified_keys"; // generate key public static final String GENERATE_KEY_ALGORITHM = "algorithm"; @@ -532,6 +534,9 @@ public class KeychainIntentService extends IntentService implements ProgressDial .getByteArray(SAVE_KEYRING_KEYS)); ArrayList keysUsages = data.getIntegerArrayList(SAVE_KEYRING_KEYS_USAGES); ArrayList keysExpiryDates = (ArrayList) data.getSerializable(SAVE_KEYRING_KEYS_EXPIRY_DATES); + ArrayList original_ids = data.getStringArrayList(SAVE_KEYRING_ORIGINAL_IDS); + ArrayList deleted_ids = data.getStringArrayList(SAVE_KEYRING_DELETED_IDS); + boolean[] modded_keys = data.getBooleanArray(SAVE_KEYRING_MODDED_KEYS); long masterKeyId = data.getLong(SAVE_KEYRING_MASTER_KEY_ID); @@ -542,8 +547,8 @@ public class KeychainIntentService extends IntentService implements ProgressDial ProviderHelper.getPGPSecretKeyRingByKeyId(this, masterKeyId), oldPassPhrase, newPassPhrase); } else { - keyOperations.buildSecretKey(userIds, keys, keysUsages, keysExpiryDates, - oldPassPhrase, newPassPhrase); + keyOperations.buildSecretKey(userIds, original_ids, deleted_ids, keys, modded_keys, + newPassPhrase, keysExpiryDates, oldPassPhrase, keysUsages); } PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassPhrase); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 132141bc5..5adb65342 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui; import java.util.ArrayList; import java.util.GregorianCalendar; +import java.util.List; import java.util.Vector; import org.spongycastle.bcpg.sig.KeyFlags; @@ -553,6 +554,15 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } } + private boolean[] toPrimitiveArray(final List booleanList) { + final boolean[] primitives = new boolean[booleanList.size()]; + int index = 0; + for (Boolean object : booleanList) { + primitives[index++] = object; + } + return primitives; + } + private void finallySaveClicked() { try { // Send all information needed to service to edit key in other thread @@ -576,6 +586,11 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener getKeysExpiryDates(mKeysView)); data.putLong(KeychainIntentService.SAVE_KEYRING_MASTER_KEY_ID, getMasterKeyId()); data.putBoolean(KeychainIntentService.SAVE_KEYRING_CAN_SIGN, masterCanSign); + data.putStringArrayList(KeychainIntentService.SAVE_KEYRING_ORIGINAL_IDS, ); + data.putBooleanArray(KeychainIntentService.SAVE_KEYRING_ORIGINAL_IDS, + toPrimitiveArray(mUserIdsView.getNeedsSavingArray())); + data.putBooleanArray(KeychainIntentService.SAVE_KEYRING_MODDED_KEYS, + toPrimitiveArray(mKeysView.getNeedsSavingArray())); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 315a8faba..5eaf54841 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -16,6 +16,8 @@ package org.sufficientlysecure.keychain.ui.widget; +import java.util.ArrayList; +import java.util.List; import java.util.Vector; import org.spongycastle.openpgp.PGPKeyFlags; @@ -162,6 +164,23 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor return ret; } + public List getNeedsSavingArray() + { + ArrayList mList = new ArrayList(); + for (int i = 0; i < mEditors.getChildCount(); ++i) { + Editor editor = (Editor) mEditors.getChildAt(i); + if (mType == Id.type.user_id) { + try { + if (((UserIdEditor)editor).getValue().equals("")) //other code ignores empty user id + continue; + } catch (UserIdEditor.InvalidEmailException e) { + } + } + mList.add(editor.needsSaving()); + } + return mList; + } + /** {@inheritDoc} */ public void onClick(View v) { if (canEdit) { -- cgit v1.2.3 From ba62d30563ee5dd316528decd272f1bbdcbee5bd Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Fri, 14 Feb 2014 17:40:11 +0000 Subject: propgate through --- .../keychain/ui/EditKeyActivity.java | 7 +++--- .../keychain/ui/widget/SectionView.java | 29 ++++++++++++++++------ .../keychain/ui/widget/UserIdEditor.java | 7 ++++++ 3 files changed, 33 insertions(+), 10 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 5adb65342..9ebe73197 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -586,9 +586,10 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener getKeysExpiryDates(mKeysView)); data.putLong(KeychainIntentService.SAVE_KEYRING_MASTER_KEY_ID, getMasterKeyId()); data.putBoolean(KeychainIntentService.SAVE_KEYRING_CAN_SIGN, masterCanSign); - data.putStringArrayList(KeychainIntentService.SAVE_KEYRING_ORIGINAL_IDS, ); - data.putBooleanArray(KeychainIntentService.SAVE_KEYRING_ORIGINAL_IDS, - toPrimitiveArray(mUserIdsView.getNeedsSavingArray())); + data.putStringArrayList(KeychainIntentService.SAVE_KEYRING_DELETED_IDS, + mUserIdsView.getDeletedIDs()); + data.putStringArrayList(KeychainIntentService.SAVE_KEYRING_ORIGINAL_IDS, + mUserIdsView.getOriginalIDs()); data.putBooleanArray(KeychainIntentService.SAVE_KEYRING_MODDED_KEYS, toPrimitiveArray(mKeysView.getNeedsSavingArray())); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 5eaf54841..788a80a60 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -65,6 +65,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor private int mNewKeySize; private boolean canEdit = true; private boolean oldItemDeleted = false; + private ArrayList mDeletedIDs = new ArrayList(); private ActionBarActivity mActivity; @@ -135,6 +136,8 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor /** {@inheritDoc} */ public void onDeleted(Editor editor, boolean wasNewItem) { oldItemDeleted |= !wasNewItem; + if (oldItemDeleted && mType == Id.type.user_id) + mDeletedIDs.add(((UserIdEditor)editor).getOriginalID()); this.updateEditorsVisible(); if (mEditorListener != null) { mEditorListener.onEdited(); @@ -164,18 +167,30 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor return ret; } + public ArrayList getOriginalIDs() + { + ArrayList orig = new ArrayList(); + if (mType == Id.type.user_id) { + for (int i = 0; i < mEditors.getChildCount(); ++i) { + UserIdEditor editor = (UserIdEditor) mEditors.getChildAt(i); + orig.add(editor.getOriginalID()); + } + return orig; + } else { + return null; + } + } + + public ArrayList getDeletedIDs() + { + return mDeletedIDs; + } + public List getNeedsSavingArray() { ArrayList mList = new ArrayList(); for (int i = 0; i < mEditors.getChildCount(); ++i) { Editor editor = (Editor) mEditors.getChildAt(i); - if (mType == Id.type.user_id) { - try { - if (((UserIdEditor)editor).getValue().equals("")) //other code ignores empty user id - continue; - } catch (UserIdEditor.InvalidEmailException e) { - } - } mList.add(editor.needsSaving()); } return mList; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index b499a429a..37ab0e051 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -40,6 +40,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene private BootstrapButton mDeleteButton; private RadioButton mIsMainUserId; + private String mOriginalID; private EditText mName; private String mOriginalName; private EditText mEmail; @@ -130,6 +131,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene mEmail.setText(""); mOriginalEmail = ""; mIsNewId = isNewId; + mOriginalID = userId; String[] result = PgpKeyHelper.splitUserId(userId); if (result[0] != null) { @@ -226,4 +228,9 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene retval |= mIsNewId; return retval; } + + public String getOriginalID() + { + return mOriginalID; + } } -- cgit v1.2.3 From c9d9c800b609d4bc9ed4b9f20a4085d4ad3f13bc Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 15 Feb 2014 14:45:57 +0000 Subject: pass through deleted keys --- .../sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 2 +- .../keychain/service/KeychainIntentService.java | 5 ++++- .../sufficientlysecure/keychain/ui/EditKeyActivity.java | 3 +++ .../keychain/ui/widget/SectionView.java | 15 +++++++++++++-- 4 files changed, 21 insertions(+), 4 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 505d3ba55..c57718540 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -198,7 +198,7 @@ public class PgpKeyOperation { } - public void buildSecretKey(ArrayList userIds, ArrayList OriginalIDs, ArrayList deletedIDs, ArrayList keys, boolean[] modded_keys, String newPassPhrase, ArrayList keysExpiryDates, String oldPassPhrase, ArrayList keysUsages) throws PgpGeneralException, + public void buildSecretKey(ArrayList userIds, ArrayList OriginalIDs, ArrayList deletedIDs, ArrayList keys, boolean[] modded_keys, ArrayList deleted_keys, ArrayList keysExpiryDates, ArrayList keysUsages, String newPassPhrase, String oldPassPhrase) throws PgpGeneralException, PGPException, SignatureException, IOException { Log.d(Constants.TAG, "userIds: " + userIds.toString()); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 4cace2658..5e5735c88 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -137,6 +137,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial public static final String SAVE_KEYRING_ORIGINAL_IDS = "original_ids"; public static final String SAVE_KEYRING_DELETED_IDS = "deleted_ids"; public static final String SAVE_KEYRING_MODDED_KEYS = "modified_keys"; + public static final String SAVE_KEYRING_DELETED_KEYS = "deleted_keys"; // generate key public static final String GENERATE_KEY_ALGORITHM = "algorithm"; @@ -537,6 +538,8 @@ public class KeychainIntentService extends IntentService implements ProgressDial ArrayList original_ids = data.getStringArrayList(SAVE_KEYRING_ORIGINAL_IDS); ArrayList deleted_ids = data.getStringArrayList(SAVE_KEYRING_DELETED_IDS); boolean[] modded_keys = data.getBooleanArray(SAVE_KEYRING_MODDED_KEYS); + ArrayList deletedKeys = PgpConversionHelper.BytesToPGPSecretKeyList(data + .getByteArray(SAVE_KEYRING_DELETED_KEYS)); long masterKeyId = data.getLong(SAVE_KEYRING_MASTER_KEY_ID); @@ -548,7 +551,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial oldPassPhrase, newPassPhrase); } else { keyOperations.buildSecretKey(userIds, original_ids, deleted_ids, keys, modded_keys, - newPassPhrase, keysExpiryDates, oldPassPhrase, keysUsages); + deletedKeys, keysExpiryDates, keysUsages, newPassPhrase, oldPassPhrase); } PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassPhrase); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 9ebe73197..ec7dd1330 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -580,6 +580,9 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener ArrayList keys = getKeys(mKeysView); data.putByteArray(KeychainIntentService.SAVE_KEYRING_KEYS, PgpConversionHelper.PGPSecretKeyArrayListToBytes(keys)); + ArrayList dKeys = mKeysView.getDeletedKeys(); + data.putByteArray(KeychainIntentService.SAVE_KEYRING_DELETED_KEYS, + PgpConversionHelper.PGPSecretKeyArrayListToBytes(dKeys)); data.putIntegerArrayList(KeychainIntentService.SAVE_KEYRING_KEYS_USAGES, getKeysUsages(mKeysView)); data.putSerializable(KeychainIntentService.SAVE_KEYRING_KEYS_EXPIRY_DATES, diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 788a80a60..369288d2c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -66,6 +66,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor private boolean canEdit = true; private boolean oldItemDeleted = false; private ArrayList mDeletedIDs = new ArrayList(); + private ArrayList mDeletedKeys = new ArrayList(); private ActionBarActivity mActivity; @@ -136,8 +137,13 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor /** {@inheritDoc} */ public void onDeleted(Editor editor, boolean wasNewItem) { oldItemDeleted |= !wasNewItem; - if (oldItemDeleted && mType == Id.type.user_id) - mDeletedIDs.add(((UserIdEditor)editor).getOriginalID()); + if (oldItemDeleted) { + if (mType == Id.type.user_id) + mDeletedIDs.add(((UserIdEditor)editor).getOriginalID()); + else if (mType == Id.type.key) + mDeletedKeys.add(((KeyEditor)editor).getValue()); + + } this.updateEditorsVisible(); if (mEditorListener != null) { mEditorListener.onEdited(); @@ -186,6 +192,11 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor return mDeletedIDs; } + public ArrayList getDeletedKeys() + { + return mDeletedKeys; + } + public List getNeedsSavingArray() { ArrayList mList = new ArrayList(); -- cgit v1.2.3 From 034deaacba5cdccf422fbba26d6244c0a4cf2554 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Fri, 21 Feb 2014 15:01:59 +0000 Subject: initial split into two functions --- .../keychain/pgp/PgpKeyOperation.java | 178 ++++++++++++++++++--- 1 file changed, 154 insertions(+), 24 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index c57718540..6055aebfc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -198,12 +198,158 @@ public class PgpKeyOperation { } - public void buildSecretKey(ArrayList userIds, ArrayList OriginalIDs, ArrayList deletedIDs, ArrayList keys, boolean[] modded_keys, ArrayList deleted_keys, ArrayList keysExpiryDates, ArrayList keysUsages, String newPassPhrase, String oldPassPhrase) throws PgpGeneralException, + private void buildNewSecretKey(ArrayList userIds, ArrayList keys, ArrayList keysExpiryDates, ArrayList keysUsages, String newPassPhrase, String oldPassPhrase) throws PgpGeneralException, PGPException, SignatureException, IOException { - Log.d(Constants.TAG, "userIds: " + userIds.toString()); + int usageId = keysUsages.get(0); + boolean canSign; + String mainUserId = userIds.get(0); + + PGPSecretKey masterKey = keys.get(0); + + // this removes all userIds and certifications previously attached to the masterPublicKey + PGPPublicKey masterPublicKey = masterKey.getPublicKey(); + + PGPSecretKeyRing mKR = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, masterKey.getKeyID()); + + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassPhrase.toCharArray()); + PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor); + + updateProgress(R.string.progress_certifying_master_key, 20, 100); + int user_id_index = 0; + for (String userId : userIds) { + PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( + masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); + + sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); + + PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); + masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); + user_id_index++; + } + + PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey); + + PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); + PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); + + hashedPacketsGen.setKeyFlags(true, usageId); + + hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS); + hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS); + hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS); + + if (keysExpiryDates.get(0) != null) { + GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + creationDate.setTime(masterPublicKey.getCreationTime()); + GregorianCalendar expiryDate = keysExpiryDates.get(0); + //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c + //here we purposefully ignore partial days in each date - long type has no fractional part! + long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); + if (numDays <= 0) + throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation)); + hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); + } else { + hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, + //this happens anyway + } + + updateProgress(R.string.progress_building_master_key, 30, 100); + + // define hashing and signing algos + PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get( + HashAlgorithmTags.SHA1); + PGPContentSignerBuilder certificationSignerBuilder = new JcaPGPContentSignerBuilder( + masterKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1); + + // Build key encrypter based on passphrase + PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder( + PGPEncryptedData.CAST5, sha1Calc) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + newPassPhrase.toCharArray()); + + PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, + masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(), + unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor); + + updateProgress(R.string.progress_adding_sub_keys, 40, 100); + + for (int i = 1; i < keys.size(); ++i) { + updateProgress(40 + 50 * (i - 1) / (keys.size() - 1), 100); + + PGPSecretKey subKey = keys.get(i); + PGPPublicKey subPublicKey = subKey.getPublicKey(); + + PBESecretKeyDecryptor keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + oldPassPhrase.toCharArray()); + PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2); + + // TODO: now used without algorithm and creation time?! (APG 1) + PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey, subPrivateKey); + + hashedPacketsGen = new PGPSignatureSubpacketGenerator(); + unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); + + usageId = keysUsages.get(i); + canSign = (usageId & KeyFlags.SIGN_DATA) > 0; //todo - separate function for this + if (canSign) { + Date todayDate = new Date(); //both sig times the same + // cross-certify signing keys + hashedPacketsGen.setSignatureCreationTime(false, todayDate); //set outer creation time + PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); + subHashedPacketsGen.setSignatureCreationTime(false, todayDate); //set inner creation time + PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( + subPublicKey.getAlgorithm(), PGPUtil.SHA1) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); + sGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey); + sGen.setHashedSubpackets(subHashedPacketsGen.generate()); + PGPSignature certification = sGen.generateCertification(masterPublicKey, + subPublicKey); + unhashedPacketsGen.setEmbeddedSignature(false, certification); + } + hashedPacketsGen.setKeyFlags(false, usageId); + + if (keysExpiryDates.get(i) != null) { + GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + creationDate.setTime(subPublicKey.getCreationTime()); + GregorianCalendar expiryDate = keysExpiryDates.get(i); + //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c + //here we purposefully ignore partial days in each date - long type has no fractional part! + long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); + if (numDays <= 0) + throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation)); + hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); + } else { + hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, + //this happens anyway + } + + keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate()); + } + + PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing(); + PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing(); + + updateProgress(R.string.progress_saving_key_ring, 90, 100); + + ProviderHelper.saveKeyRing(mContext, secretKeyRing); + ProviderHelper.saveKeyRing(mContext, publicKeyRing); + + updateProgress(R.string.progress_done, 100, 100); + } + + public void buildSecretKey(ArrayList userIds, ArrayList OriginalIDs, ArrayList deletedIDs, ArrayList keys, boolean[] modded_keys, ArrayList deleted_keys, ArrayList keysExpiryDates, ArrayList keysUsages, String newPassPhrase, String oldPassPhrase) throws PgpGeneralException, + PGPException, SignatureException, IOException { updateProgress(R.string.progress_building_key, 0, 100); + PGPSecretKey masterKey = keys.get(0); + + PGPSecretKeyRing mKR = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, masterKey.getKeyID()); if (oldPassPhrase == null) { oldPassPhrase = ""; @@ -212,41 +358,25 @@ public class PgpKeyOperation { newPassPhrase = ""; } - updateProgress(R.string.progress_preparing_master_key, 10, 100); + if (mKR == null) + buildNewSecretKey(userIds, keys, keysExpiryDates, keysUsages, newPassPhrase, oldPassPhrase); //new Keyring + + masterKey = mKR.getSecretKey(); + PGPPublicKey masterPublicKey = masterKey.getPublicKey(); int usageId = keysUsages.get(0); boolean canSign; String mainUserId = userIds.get(0); - PGPSecretKey masterKey = keys.get(0); - - // this removes all userIds and certifications previously attached to the masterPublicKey - PGPPublicKey masterPublicKey = masterKey.getPublicKey(); - - // already done by code above: - // PGPPublicKey masterPublicKey = masterKey.getPublicKey(); - // // Somehow, the PGPPublicKey already has an empty certification attached to it when the - // // keyRing is generated the first time, we remove that when it exists, before adding the - // new - // // ones - // PGPPublicKey masterPublicKeyRmCert = PGPPublicKey.removeCertification(masterPublicKey, - // ""); - // if (masterPublicKeyRmCert != null) { - // masterPublicKey = masterPublicKeyRmCert; - // } - - - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassPhrase.toCharArray()); PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor); updateProgress(R.string.progress_certifying_master_key, 20, 100); - // TODO: if we are editing a key, keep old certs, don't remake certs we don't have to. int user_id_index = 0; for (String userId : userIds) { - if (OriginalIDs[user_id_index]) { + if (!OriginalIDs.get(user_id_index).equals(userIds.get(user_id_index))) { PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); -- cgit v1.2.3 From c3c311152ef33a6887909dbbeae40e8d01f96a9d Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Fri, 21 Feb 2014 15:09:49 +0000 Subject: put main original id at the top --- .../java/org/sufficientlysecure/keychain/ui/widget/SectionView.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 369288d2c..2e06f3f34 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -179,7 +179,10 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor if (mType == Id.type.user_id) { for (int i = 0; i < mEditors.getChildCount(); ++i) { UserIdEditor editor = (UserIdEditor) mEditors.getChildAt(i); - orig.add(editor.getOriginalID()); + if (editor.isMainUserId()) + orig.add(0, editor.getOriginalID()); + else + orig.add(editor.getOriginalID()); } return orig; } else { -- cgit v1.2.3 From 1a28a4e9214add62b2b1e23b4579e0a4d585f52e Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 22 Feb 2014 13:54:59 +0000 Subject: change how primary id changing is passed through --- .../sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 4 ++-- .../keychain/service/KeychainIntentService.java | 7 +++++-- .../org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 2 ++ .../sufficientlysecure/keychain/ui/widget/SectionView.java | 13 +++++++++++++ .../sufficientlysecure/keychain/ui/widget/UserIdEditor.java | 7 ++++++- 5 files changed, 28 insertions(+), 5 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 80831d35f..cc9384821 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -343,7 +343,7 @@ public class PgpKeyOperation { updateProgress(R.string.progress_done, 100, 100); } - public void buildSecretKey(ArrayList userIds, ArrayList OriginalIDs, ArrayList deletedIDs, ArrayList keys, boolean[] modded_keys, ArrayList deleted_keys, ArrayList keysExpiryDates, ArrayList keysUsages, String newPassPhrase, String oldPassPhrase) throws PgpGeneralException, + public void buildSecretKey(ArrayList userIds, ArrayList OriginalIDs, ArrayList deletedIDs, boolean primaryIDChanged, boolean[] modded_keys, ArrayList deleted_keys, ArrayList keysExpiryDates, ArrayList keysUsages, String newPassPhrase, String oldPassPhrase, ArrayList keys) throws PgpGeneralException, PGPException, SignatureException, IOException { updateProgress(R.string.progress_building_key, 0, 100); @@ -386,7 +386,7 @@ public class PgpKeyOperation { PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); - masterPublicKey = PGPPublicKey.removeCertification(); + //masterPublicKey = PGPPublicKey.removeCertification(); masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); } user_id_index++; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 9e517b93e..73de7ca6e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -128,6 +128,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial public static final String SAVE_KEYRING_NEW_PASSPHRASE = "new_passphrase"; public static final String SAVE_KEYRING_CURRENT_PASSPHRASE = "current_passphrase"; public static final String SAVE_KEYRING_USER_IDS = "user_ids"; + public static final String SAVE_KEYRING_PRIMARY_ID_CHANGED = "primary_id_changed"; public static final String SAVE_KEYRING_KEYS = "keys"; public static final String SAVE_KEYRING_KEYS_USAGES = "keys_usages"; public static final String SAVE_KEYRING_KEYS_EXPIRY_DATES = "keys_expiry_dates"; @@ -549,6 +550,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial boolean[] modded_keys = data.getBooleanArray(SAVE_KEYRING_MODDED_KEYS); ArrayList deletedKeys = PgpConversionHelper.BytesToPGPSecretKeyList(data .getByteArray(SAVE_KEYRING_DELETED_KEYS)); + boolean primaryChanged = data.getBoolean(SAVE_KEYRING_PRIMARY_ID_CHANGED); long masterKeyId = data.getLong(SAVE_KEYRING_MASTER_KEY_ID); @@ -559,8 +561,9 @@ public class KeychainIntentService extends IntentService implements ProgressDial ProviderHelper.getPGPSecretKeyRingByKeyId(this, masterKeyId), oldPassPhrase, newPassPhrase); } else { - keyOperations.buildSecretKey(userIds, original_ids, deleted_ids, keys, modded_keys, - deletedKeys, keysExpiryDates, keysUsages, newPassPhrase, oldPassPhrase); + keyOperations.buildSecretKey(userIds, original_ids, deleted_ids, primaryChanged, + modded_keys, deletedKeys, keysExpiryDates, keysUsages, newPassPhrase, + oldPassPhrase, keys); } PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassPhrase); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index ec7dd1330..09be0dc79 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -595,6 +595,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener mUserIdsView.getOriginalIDs()); data.putBooleanArray(KeychainIntentService.SAVE_KEYRING_MODDED_KEYS, toPrimitiveArray(mKeysView.getNeedsSavingArray())); + data.putBoolean(KeychainIntentService.SAVE_KEYRING_PRIMARY_ID_CHANGED, + mUserIdsView.primaryChanged()); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 2e06f3f34..014a891a5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -169,6 +169,19 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor for (int i = 0; i < mEditors.getChildCount(); ++i) { Editor editor = (Editor) mEditors.getChildAt(i); ret |= editor.needsSaving(); + if (mType == Id.type.user_id) + ret |= ((UserIdEditor)editor).primarySwapped(); + } + return ret; + } + + public boolean primaryChanged() + { + boolean ret = false; + for (int i = 0; i < mEditors.getChildCount(); ++i) { + Editor editor = (Editor) mEditors.getChildAt(i); + if (mType == Id.type.user_id) + ret |= ((UserIdEditor)editor).primarySwapped(); } return ret; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index 37ab0e051..5098c8713 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -221,7 +221,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene @Override public boolean needsSaving() { - boolean retval = (mOriginallyMainUserID != isMainUserId()); + boolean retval = false; //(mOriginallyMainUserID != isMainUserId()); retval |= !(mOriginalName.equals( ("" + mName.getText()).trim() ) ); retval |= !(mOriginalEmail.equals( ("" + mEmail.getText()).trim() ) ); retval |= !(mOriginalComment.equals( ("" + mComment.getText()).trim() ) ); @@ -229,6 +229,11 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene return retval; } + public boolean primarySwapped() + { + return (mOriginallyMainUserID != isMainUserId()); + } + public String getOriginalID() { return mOriginalID; -- cgit v1.2.3 From a39c73ca12dabba01412083afbf0b58dfb42a79e Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 22 Feb 2014 15:29:19 +0000 Subject: first go at saving IDs correctly --- .../keychain/pgp/PgpKeyOperation.java | 78 ++++++++++++++++++---- 1 file changed, 64 insertions(+), 14 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index cc9384821..f3b289f66 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -28,6 +28,7 @@ import java.security.SignatureException; import java.util.ArrayList; import java.util.Date; import java.util.GregorianCalendar; +import java.util.Iterator; import java.util.TimeZone; import org.spongycastle.bcpg.CompressionAlgorithmTags; @@ -68,6 +69,7 @@ import org.sufficientlysecure.keychain.util.Primes; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; import android.content.Context; +import android.util.Pair; public class PgpKeyOperation { private final Context mContext; @@ -361,6 +363,21 @@ public class PgpKeyOperation { if (mKR == null) buildNewSecretKey(userIds, keys, keysExpiryDates, keysUsages, newPassPhrase, oldPassPhrase); //new Keyring + /* + IDs - + remove deleted ids + if the primary ID changed we need to: + remove all of the IDs from the keyring, saving their certifications + add them all in again, updating certs of IDs which have changed + else + remove changed IDs and add in with new certs + + Keys + remove deleted keys + if a key is modified, re-sign it + do we need to remove and add in? + */ + masterKey = mKR.getSecretKey(); PGPPublicKey masterPublicKey = masterKey.getPublicKey(); @@ -374,22 +391,55 @@ public class PgpKeyOperation { updateProgress(R.string.progress_certifying_master_key, 20, 100); - int user_id_index = 0; - for (String userId : userIds) { - if (!OriginalIDs.get(user_id_index).equals(userIds.get(user_id_index))) { - PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); - - sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); - - PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); + for (String delID : deletedIDs) { + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, delID); + } - //masterPublicKey = PGPPublicKey.removeCertification(); - masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); + int user_id_index = 0; + if (primaryIDChanged) { + ArrayList> sigList = new ArrayList>(); + for (String userId : userIds) { + String orig_id = OriginalIDs.get(user_id_index); + if (orig_id.equals(userId)) { + Iterator orig_sigs = masterPublicKey.getSignaturesForID(orig_id); //TODO: make sure this iterator only has signatures we are interested in + while (orig_sigs.hasNext()) { + PGPSignature orig_sig = orig_sigs.next(); + sigList.add(new Pair(orig_id, orig_sig)); + } + } else { + PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( + masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); + + sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); + + PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); + sigList.add(new Pair(userId, certification)); + } + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, orig_id); + user_id_index++; + } + for (Pair to_add : sigList) { + masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, to_add.first, to_add.second); + } + } else { + for (String userId : userIds) { + String orig_id = OriginalIDs.get(user_id_index); + if (!orig_id.equals(userId)) { + PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( + masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); + + sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); + + PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, orig_id); + masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); + } + user_id_index++; } - user_id_index++; } PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey); -- cgit v1.2.3 From fab74590eb0984e055f98ccf3af4390d3e3c0c15 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 22 Feb 2014 15:41:15 +0000 Subject: remove deleted keys --- .../java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index f3b289f66..ab4408056 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -378,6 +378,10 @@ public class PgpKeyOperation { do we need to remove and add in? */ + for (PGPSecretKey dKey : deleted_keys) { + mKR = PGPSecretKeyRing.removeSecretKey(mKR, dKey); + } + masterKey = mKR.getSecretKey(); PGPPublicKey masterPublicKey = masterKey.getPublicKey(); -- cgit v1.2.3 From fa533dda325b5d56db16dee2f84152ec4807a2b2 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 22 Feb 2014 16:08:38 +0000 Subject: pass through which keys are new --- .../org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 9 +++++++-- .../keychain/service/KeychainIntentService.java | 4 +++- .../org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 2 ++ .../org/sufficientlysecure/keychain/ui/widget/KeyEditor.java | 5 +++++ .../sufficientlysecure/keychain/ui/widget/SectionView.java | 12 ++++++++++++ 5 files changed, 29 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index ab4408056..a6ff60442 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -345,7 +345,7 @@ public class PgpKeyOperation { updateProgress(R.string.progress_done, 100, 100); } - public void buildSecretKey(ArrayList userIds, ArrayList OriginalIDs, ArrayList deletedIDs, boolean primaryIDChanged, boolean[] modded_keys, ArrayList deleted_keys, ArrayList keysExpiryDates, ArrayList keysUsages, String newPassPhrase, String oldPassPhrase, ArrayList keys) throws PgpGeneralException, + public void buildSecretKey(ArrayList userIds, ArrayList OriginalIDs, ArrayList deletedIDs, boolean primaryIDChanged, boolean[] modded_keys, ArrayList deleted_keys, ArrayList keysExpiryDates, ArrayList keysUsages, String newPassPhrase, String oldPassPhrase, boolean[] new_keys, ArrayList keys) throws PgpGeneralException, PGPException, SignatureException, IOException { updateProgress(R.string.progress_building_key, 0, 100); @@ -490,6 +490,11 @@ public class PgpKeyOperation { masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(), unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor); + //updating master is slightly different to updating the others + if (modded_keys[0]) { + + } + updateProgress(R.string.progress_adding_sub_keys, 40, 100); for (int i = 1; i < keys.size(); ++i) { @@ -549,7 +554,7 @@ public class PgpKeyOperation { PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing(); PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing(); - +//must copy with new passphrase... new keys will have an empty passphrase... pass in boolean array to mark new key? updateProgress(R.string.progress_saving_key_ring, 90, 100); ProviderHelper.saveKeyRing(mContext, secretKeyRing); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 73de7ca6e..3610ddc9e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -138,6 +138,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial public static final String SAVE_KEYRING_DELETED_IDS = "deleted_ids"; public static final String SAVE_KEYRING_MODDED_KEYS = "modified_keys"; public static final String SAVE_KEYRING_DELETED_KEYS = "deleted_keys"; + public static final String SAVE_KEYRING_NEW_KEYS = "new_keys"; // generate key public static final String GENERATE_KEY_ALGORITHM = "algorithm"; @@ -548,6 +549,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial ArrayList original_ids = data.getStringArrayList(SAVE_KEYRING_ORIGINAL_IDS); ArrayList deleted_ids = data.getStringArrayList(SAVE_KEYRING_DELETED_IDS); boolean[] modded_keys = data.getBooleanArray(SAVE_KEYRING_MODDED_KEYS); + boolean[] new_keys = data.getBooleanArray(SAVE_KEYRING_NEW_KEYS); ArrayList deletedKeys = PgpConversionHelper.BytesToPGPSecretKeyList(data .getByteArray(SAVE_KEYRING_DELETED_KEYS)); boolean primaryChanged = data.getBoolean(SAVE_KEYRING_PRIMARY_ID_CHANGED); @@ -563,7 +565,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial } else { keyOperations.buildSecretKey(userIds, original_ids, deleted_ids, primaryChanged, modded_keys, deletedKeys, keysExpiryDates, keysUsages, newPassPhrase, - oldPassPhrase, keys); + oldPassPhrase, new_keys, keys); } PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassPhrase); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 09be0dc79..bb38ac979 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -597,6 +597,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener toPrimitiveArray(mKeysView.getNeedsSavingArray())); data.putBoolean(KeychainIntentService.SAVE_KEYRING_PRIMARY_ID_CHANGED, mUserIdsView.primaryChanged()); + data.putBooleanArray(KeychainIntentService.SAVE_KEYRING_NEW_KEYS, + toPrimitiveArray(mKeysView.getNewKeysArray())); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 5ce5d89d7..68bfc573e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -314,4 +314,9 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { return retval; } + public boolean getIsNewKey() + { + return mIsNewKey; + } + } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 014a891a5..93c10a2b0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -223,6 +223,18 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor return mList; } + public List getNewKeysArray() + { + ArrayList mList = new ArrayList(); + if (mType == Id.type.key) { + for (int i = 0; i < mEditors.getChildCount(); ++i) { + KeyEditor editor = (KeyEditor) mEditors.getChildAt(i); + mList.add(editor.getIsNewKey()); + } + } + return mList; + } + /** {@inheritDoc} */ public void onClick(View v) { if (canEdit) { -- cgit v1.2.3 From d6b0975f9b666dc30edab36e6f2c68c0022790d1 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sun, 2 Mar 2014 20:34:28 +0000 Subject: begin adding parcel for save intent --- .../keychain/pgp/PgpKeyOperation.java | 10 ++- .../keychain/service/SaveKeyringParcel.java | 90 ++++++++++++++++++++++ 2 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index a6ff60442..a52f247c6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.GregorianCalendar; import java.util.Iterator; +import java.util.List; import java.util.TimeZone; import org.spongycastle.bcpg.CompressionAlgorithmTags; @@ -490,11 +491,14 @@ public class PgpKeyOperation { masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(), unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor); - //updating master is slightly different to updating the others - if (modded_keys[0]) { + for (int i = 0; i < keys.size(); ++i) { + updateProgress(40 + 50 * (i - 1) / (keys.size() - 1), 100); + if (new_keys[i]) { - } + } else { + } + } updateProgress(R.string.progress_adding_sub_keys, 40, 100); for (int i = 1; i < keys.size(); ++i) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java new file mode 100644 index 000000000..bdabc70a2 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2014 Ash Hughes + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + + +package org.sufficientlysecure.keychain.service; + +import android.os.Parcel; +import android.os.Parcelable; + +import org.spongycastle.openpgp.PGPSecretKey; +import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; + +import java.util.ArrayList; +import java.util.GregorianCalendar; + +public class SaveKeyringParcel implements Parcelable { + + public ArrayList userIDs; + public ArrayList originalIDs; + public ArrayList deletedIDs; + public boolean primaryIDChanged; + public boolean[] moddedKeys; + public ArrayList deletedKeys; + public ArrayList keysExpiryDates; + public ArrayList keysUsages; + public String newPassPhrase; + public String oldPassPhrase; + public boolean[] newKeys; + public ArrayList keys; + + private SaveKeyringParcel(Parcel source) + { + byte[] tmpB; + userIDs = (ArrayList)source.readSerializable(); + originalIDs = (ArrayList)source.readSerializable(); + deletedIDs = (ArrayList)source.readSerializable(); + primaryIDChanged = source.readByte() != 0; + source.readBooleanArray(moddedKeys); + deletedKeys = PgpConversionHelper.BytesToPGPSecretKeyList(source.createByteArray()); + keysExpiryDates = (ArrayList)source.readSerializable(); + keysUsages = source.readArrayList(Integer.class.getClassLoader()); + } + + @Override + public void writeToParcel(Parcel destination, int flags) + { + destination.writeSerializable(userIDs); + destination.writeSerializable(originalIDs); + destination.writeSerializable(deletedIDs); + destination.writeByte((byte) (primaryIDChanged ? 1 : 0)); + destination.writeBooleanArray(moddedKeys); + destination.writeByteArray(PgpConversionHelper.PGPSecretKeyArrayListToBytes(deletedKeys)); + destination.writeSerializable(keysExpiryDates); + destination.writeList(keysUsages); + destination.writeString(newPassPhrase); + destination.writeString(oldPassPhrase); + destination.writeBooleanArray(newKeys); + destination.writeByteArray(); + } + + public static final Creator CREATOR = new Creator() { + public SaveKeyringParcel createFromParcel(final Parcel source) { + return new SaveKeyringParcel(source); + } + + public SaveKeyringParcel[] newArray(final int size) { + return new SaveKeyringParcel[size]; + } + }; + + @Override + public int describeContents() + { + return 0; + } +} -- cgit v1.2.3 From 8662ca2928ac0b007d4ee5d00f6de3211f5d3d2c Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Mar 2014 12:25:35 +0000 Subject: a method, if not the best one, for each property --- .../sufficientlysecure/keychain/service/SaveKeyringParcel.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index bdabc70a2..9e290c1b6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -53,12 +53,16 @@ public class SaveKeyringParcel implements Parcelable { deletedKeys = PgpConversionHelper.BytesToPGPSecretKeyList(source.createByteArray()); keysExpiryDates = (ArrayList)source.readSerializable(); keysUsages = source.readArrayList(Integer.class.getClassLoader()); + newPassPhrase = source.readString(); + oldPassPhrase = source.readString(); + source.readBooleanArray(newKeys); + keys = PgpConversionHelper.BytesToPGPSecretKeyList(source.createByteArray()); } @Override public void writeToParcel(Parcel destination, int flags) { - destination.writeSerializable(userIDs); + destination.writeSerializable(userIDs); //might not be the best method to store. destination.writeSerializable(originalIDs); destination.writeSerializable(deletedIDs); destination.writeByte((byte) (primaryIDChanged ? 1 : 0)); @@ -69,7 +73,7 @@ public class SaveKeyringParcel implements Parcelable { destination.writeString(newPassPhrase); destination.writeString(oldPassPhrase); destination.writeBooleanArray(newKeys); - destination.writeByteArray(); + destination.writeByteArray(PgpConversionHelper.PGPSecretKeyArrayListToBytes(keys)); } public static final Creator CREATOR = new Creator() { -- cgit v1.2.3 From 01951810ae1b3a0e4fefab7d55c090fc8f776ce5 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Mar 2014 13:00:17 +0000 Subject: fix saving new key (tmp) --- .../java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 4 +++- .../sufficientlysecure/keychain/service/KeychainIntentService.java | 7 ++++++- .../java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 5 ++++- 3 files changed, 13 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index a52f247c6..66665df3c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -361,8 +361,10 @@ public class PgpKeyOperation { newPassPhrase = ""; } - if (mKR == null) + if (mKR == null) { buildNewSecretKey(userIds, keys, keysExpiryDates, keysUsages, newPassPhrase, oldPassPhrase); //new Keyring + return; + } /* IDs - diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 3610ddc9e..9d6e24d30 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -550,8 +550,13 @@ public class KeychainIntentService extends IntentService implements ProgressDial ArrayList deleted_ids = data.getStringArrayList(SAVE_KEYRING_DELETED_IDS); boolean[] modded_keys = data.getBooleanArray(SAVE_KEYRING_MODDED_KEYS); boolean[] new_keys = data.getBooleanArray(SAVE_KEYRING_NEW_KEYS); - ArrayList deletedKeys = PgpConversionHelper.BytesToPGPSecretKeyList(data + byte[] tmp = data.getByteArray(SAVE_KEYRING_DELETED_KEYS); + ArrayList deletedKeys; + if (tmp != null) + deletedKeys = PgpConversionHelper.BytesToPGPSecretKeyList(data .getByteArray(SAVE_KEYRING_DELETED_KEYS)); + else + deletedKeys = new ArrayList(); boolean primaryChanged = data.getBoolean(SAVE_KEYRING_PRIMARY_ID_CHANGED); long masterKeyId = data.getLong(SAVE_KEYRING_MASTER_KEY_ID); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index bb38ac979..044d15ec7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -581,8 +581,11 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener data.putByteArray(KeychainIntentService.SAVE_KEYRING_KEYS, PgpConversionHelper.PGPSecretKeyArrayListToBytes(keys)); ArrayList dKeys = mKeysView.getDeletedKeys(); + byte[] tmp = null; + if (dKeys.size() != 0) + tmp = PgpConversionHelper.PGPSecretKeyArrayListToBytes(dKeys); data.putByteArray(KeychainIntentService.SAVE_KEYRING_DELETED_KEYS, - PgpConversionHelper.PGPSecretKeyArrayListToBytes(dKeys)); + tmp); data.putIntegerArrayList(KeychainIntentService.SAVE_KEYRING_KEYS_USAGES, getKeysUsages(mKeysView)); data.putSerializable(KeychainIntentService.SAVE_KEYRING_KEYS_EXPIRY_DATES, -- cgit v1.2.3 From 04fa0e9cc7fbfc117948d60a3ad8bfab0b0060ba Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 6 Mar 2014 23:47:11 +0000 Subject: use parcel to save keys, but saving existing keys is disabled, pending a rewrite... --- .../keychain/pgp/PgpKeyOperation.java | 18 +++++---- .../keychain/service/KeychainIntentService.java | 45 ++++----------------- .../keychain/service/SaveKeyringParcel.java | 18 ++++++--- .../keychain/ui/EditKeyActivity.java | 46 ++++++++-------------- 4 files changed, 49 insertions(+), 78 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 66665df3c..0073107a0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -65,6 +65,7 @@ import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Primes; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; @@ -346,23 +347,24 @@ public class PgpKeyOperation { updateProgress(R.string.progress_done, 100, 100); } - public void buildSecretKey(ArrayList userIds, ArrayList OriginalIDs, ArrayList deletedIDs, boolean primaryIDChanged, boolean[] modded_keys, ArrayList deleted_keys, ArrayList keysExpiryDates, ArrayList keysUsages, String newPassPhrase, String oldPassPhrase, boolean[] new_keys, ArrayList keys) throws PgpGeneralException, + public void buildSecretKey(SaveKeyringParcel saveParcel) throws PgpGeneralException, PGPException, SignatureException, IOException { updateProgress(R.string.progress_building_key, 0, 100); - PGPSecretKey masterKey = keys.get(0); + PGPSecretKey masterKey = saveParcel.keys.get(0); PGPSecretKeyRing mKR = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, masterKey.getKeyID()); - if (oldPassPhrase == null) { - oldPassPhrase = ""; + if (saveParcel.oldPassPhrase == null) { + saveParcel.oldPassPhrase = ""; } - if (newPassPhrase == null) { - newPassPhrase = ""; + if (saveParcel.newPassPhrase == null) { + saveParcel.newPassPhrase = ""; } if (mKR == null) { - buildNewSecretKey(userIds, keys, keysExpiryDates, keysUsages, newPassPhrase, oldPassPhrase); //new Keyring + buildNewSecretKey(saveParcel.userIDs, saveParcel.keys, saveParcel.keysExpiryDates, + saveParcel.keysUsages, saveParcel.newPassPhrase, saveParcel.oldPassPhrase); //new Keyring return; } @@ -381,6 +383,7 @@ public class PgpKeyOperation { do we need to remove and add in? */ + /* for (PGPSecretKey dKey : deleted_keys) { mKR = PGPSecretKeyRing.removeSecretKey(mKR, dKey); } @@ -567,6 +570,7 @@ public class PgpKeyOperation { ProviderHelper.saveKeyRing(mContext, publicKeyRing); updateProgress(R.string.progress_done, 100, 100); + */ } public PGPPublicKeyRing certifyKey(long masterKeyId, long pubKeyId, String passphrase) diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 9d6e24d30..24bce8eeb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -125,20 +125,9 @@ public class KeychainIntentService extends IntentService implements ProgressDial public static final String DECRYPT_ASSUME_SYMMETRIC = "assume_symmetric"; // save keyring - public static final String SAVE_KEYRING_NEW_PASSPHRASE = "new_passphrase"; - public static final String SAVE_KEYRING_CURRENT_PASSPHRASE = "current_passphrase"; - public static final String SAVE_KEYRING_USER_IDS = "user_ids"; - public static final String SAVE_KEYRING_PRIMARY_ID_CHANGED = "primary_id_changed"; - public static final String SAVE_KEYRING_KEYS = "keys"; - public static final String SAVE_KEYRING_KEYS_USAGES = "keys_usages"; - public static final String SAVE_KEYRING_KEYS_EXPIRY_DATES = "keys_expiry_dates"; - public static final String SAVE_KEYRING_MASTER_KEY_ID = "master_key_id"; + public static final String SAVE_KEYRING_PARCEL = "save_parcel"; public static final String SAVE_KEYRING_CAN_SIGN = "can_sign"; - public static final String SAVE_KEYRING_ORIGINAL_IDS = "original_ids"; - public static final String SAVE_KEYRING_DELETED_IDS = "deleted_ids"; - public static final String SAVE_KEYRING_MODDED_KEYS = "modified_keys"; - public static final String SAVE_KEYRING_DELETED_KEYS = "deleted_keys"; - public static final String SAVE_KEYRING_NEW_KEYS = "new_keys"; + // generate key public static final String GENERATE_KEY_ALGORITHM = "algorithm"; @@ -530,8 +519,9 @@ public class KeychainIntentService extends IntentService implements ProgressDial } else if (ACTION_SAVE_KEYRING.equals(action)) { try { /* Input */ - String oldPassPhrase = data.getString(SAVE_KEYRING_CURRENT_PASSPHRASE); - String newPassPhrase = data.getString(SAVE_KEYRING_NEW_PASSPHRASE); + SaveKeyringParcel saveParams = data.getParcelable(SAVE_KEYRING_PARCEL); + String oldPassPhrase = saveParams.oldPassPhrase; + String newPassPhrase = saveParams.newPassPhrase; boolean canSign = true; if (data.containsKey(SAVE_KEYRING_CAN_SIGN)) { @@ -541,25 +531,8 @@ public class KeychainIntentService extends IntentService implements ProgressDial if (newPassPhrase == null) { newPassPhrase = oldPassPhrase; } - ArrayList userIds = data.getStringArrayList(SAVE_KEYRING_USER_IDS); - ArrayList keys = PgpConversionHelper.BytesToPGPSecretKeyList(data - .getByteArray(SAVE_KEYRING_KEYS)); - ArrayList keysUsages = data.getIntegerArrayList(SAVE_KEYRING_KEYS_USAGES); - ArrayList keysExpiryDates = (ArrayList) data.getSerializable(SAVE_KEYRING_KEYS_EXPIRY_DATES); - ArrayList original_ids = data.getStringArrayList(SAVE_KEYRING_ORIGINAL_IDS); - ArrayList deleted_ids = data.getStringArrayList(SAVE_KEYRING_DELETED_IDS); - boolean[] modded_keys = data.getBooleanArray(SAVE_KEYRING_MODDED_KEYS); - boolean[] new_keys = data.getBooleanArray(SAVE_KEYRING_NEW_KEYS); - byte[] tmp = data.getByteArray(SAVE_KEYRING_DELETED_KEYS); - ArrayList deletedKeys; - if (tmp != null) - deletedKeys = PgpConversionHelper.BytesToPGPSecretKeyList(data - .getByteArray(SAVE_KEYRING_DELETED_KEYS)); - else - deletedKeys = new ArrayList(); - boolean primaryChanged = data.getBoolean(SAVE_KEYRING_PRIMARY_ID_CHANGED); - - long masterKeyId = data.getLong(SAVE_KEYRING_MASTER_KEY_ID); + + long masterKeyId = saveParams.keys.get(0).getKeyID(); PgpKeyOperation keyOperations = new PgpKeyOperation(this, this); /* Operation */ @@ -568,9 +541,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial ProviderHelper.getPGPSecretKeyRingByKeyId(this, masterKeyId), oldPassPhrase, newPassPhrase); } else { - keyOperations.buildSecretKey(userIds, original_ids, deleted_ids, primaryChanged, - modded_keys, deletedKeys, keysExpiryDates, keysUsages, newPassPhrase, - oldPassPhrase, new_keys, keys); + keyOperations.buildSecretKey(saveParams); } PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassPhrase); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index 9e290c1b6..ae481aa80 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -42,20 +42,25 @@ public class SaveKeyringParcel implements Parcelable { public boolean[] newKeys; public ArrayList keys; + public SaveKeyringParcel() {} + private SaveKeyringParcel(Parcel source) { - byte[] tmpB; userIDs = (ArrayList)source.readSerializable(); originalIDs = (ArrayList)source.readSerializable(); deletedIDs = (ArrayList)source.readSerializable(); primaryIDChanged = source.readByte() != 0; - source.readBooleanArray(moddedKeys); - deletedKeys = PgpConversionHelper.BytesToPGPSecretKeyList(source.createByteArray()); + moddedKeys = source.createBooleanArray(); + byte[] tmp = source.createByteArray(); + if (tmp == null) + deletedKeys = null; + else + deletedKeys = PgpConversionHelper.BytesToPGPSecretKeyList(tmp); keysExpiryDates = (ArrayList)source.readSerializable(); keysUsages = source.readArrayList(Integer.class.getClassLoader()); newPassPhrase = source.readString(); oldPassPhrase = source.readString(); - source.readBooleanArray(newKeys); + newKeys = source.createBooleanArray(); keys = PgpConversionHelper.BytesToPGPSecretKeyList(source.createByteArray()); } @@ -67,7 +72,10 @@ public class SaveKeyringParcel implements Parcelable { destination.writeSerializable(deletedIDs); destination.writeByte((byte) (primaryIDChanged ? 1 : 0)); destination.writeBooleanArray(moddedKeys); - destination.writeByteArray(PgpConversionHelper.PGPSecretKeyArrayListToBytes(deletedKeys)); + byte[] tmp = null; + if (deletedKeys.size() != 0) + tmp = PgpConversionHelper.PGPSecretKeyArrayListToBytes(deletedKeys); + destination.writeByteArray(tmp); destination.writeSerializable(keysExpiryDates); destination.writeList(keysUsages); destination.writeString(newPassPhrase); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 044d15ec7..6ce2a8f6b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.PassphraseCacheService; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; @@ -570,38 +571,25 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING); + SaveKeyringParcel saveParams = new SaveKeyringParcel(); + saveParams.userIDs = getUserIds(mUserIdsView); + saveParams.originalIDs = mUserIdsView.getOriginalIDs(); + saveParams.deletedIDs = mUserIdsView.getDeletedIDs(); + saveParams.primaryIDChanged = mUserIdsView.primaryChanged(); + saveParams.moddedKeys = toPrimitiveArray(mKeysView.getNeedsSavingArray()); + saveParams.deletedKeys = mKeysView.getDeletedKeys(); + saveParams.keysExpiryDates = getKeysExpiryDates(mKeysView); + saveParams.keysUsages = getKeysUsages(mKeysView); + saveParams.newPassPhrase = mNewPassPhrase; + saveParams.oldPassPhrase = mCurrentPassPhrase; + saveParams.newKeys = toPrimitiveArray(mKeysView.getNewKeysArray()); + saveParams.keys = getKeys(mKeysView); + + // fill values for this action Bundle data = new Bundle(); - data.putString(KeychainIntentService.SAVE_KEYRING_CURRENT_PASSPHRASE, - mCurrentPassPhrase); - data.putString(KeychainIntentService.SAVE_KEYRING_NEW_PASSPHRASE, mNewPassPhrase); - data.putStringArrayList(KeychainIntentService.SAVE_KEYRING_USER_IDS, - getUserIds(mUserIdsView)); - ArrayList keys = getKeys(mKeysView); - data.putByteArray(KeychainIntentService.SAVE_KEYRING_KEYS, - PgpConversionHelper.PGPSecretKeyArrayListToBytes(keys)); - ArrayList dKeys = mKeysView.getDeletedKeys(); - byte[] tmp = null; - if (dKeys.size() != 0) - tmp = PgpConversionHelper.PGPSecretKeyArrayListToBytes(dKeys); - data.putByteArray(KeychainIntentService.SAVE_KEYRING_DELETED_KEYS, - tmp); - data.putIntegerArrayList(KeychainIntentService.SAVE_KEYRING_KEYS_USAGES, - getKeysUsages(mKeysView)); - data.putSerializable(KeychainIntentService.SAVE_KEYRING_KEYS_EXPIRY_DATES, - getKeysExpiryDates(mKeysView)); - data.putLong(KeychainIntentService.SAVE_KEYRING_MASTER_KEY_ID, getMasterKeyId()); data.putBoolean(KeychainIntentService.SAVE_KEYRING_CAN_SIGN, masterCanSign); - data.putStringArrayList(KeychainIntentService.SAVE_KEYRING_DELETED_IDS, - mUserIdsView.getDeletedIDs()); - data.putStringArrayList(KeychainIntentService.SAVE_KEYRING_ORIGINAL_IDS, - mUserIdsView.getOriginalIDs()); - data.putBooleanArray(KeychainIntentService.SAVE_KEYRING_MODDED_KEYS, - toPrimitiveArray(mKeysView.getNeedsSavingArray())); - data.putBoolean(KeychainIntentService.SAVE_KEYRING_PRIMARY_ID_CHANGED, - mUserIdsView.primaryChanged()); - data.putBooleanArray(KeychainIntentService.SAVE_KEYRING_NEW_KEYS, - toPrimitiveArray(mKeysView.getNewKeysArray())); + data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, saveParams); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); -- cgit v1.2.3 From b06e4d827a65838cc7085040ea465c1163f1cdd9 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Fri, 7 Mar 2014 15:36:01 +0000 Subject: uncomment, use Parcel. Builds, not functional --- .../keychain/pgp/PgpKeyOperation.java | 48 +++++++++++----------- 1 file changed, 23 insertions(+), 25 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index f744fbcec..87f8fdebb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -383,33 +383,32 @@ public class PgpKeyOperation { do we need to remove and add in? */ - /* - for (PGPSecretKey dKey : deleted_keys) { + for (PGPSecretKey dKey : saveParcel.deletedKeys) { mKR = PGPSecretKeyRing.removeSecretKey(mKR, dKey); } masterKey = mKR.getSecretKey(); PGPPublicKey masterPublicKey = masterKey.getPublicKey(); - int usageId = keysUsages.get(0); + int usageId = saveParcel.keysUsages.get(0); boolean canSign; - String mainUserId = userIds.get(0); + String mainUserId = saveParcel.userIDs.get(0); PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassPhrase.toCharArray()); + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(saveParcel.oldPassPhrase.toCharArray()); PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor); updateProgress(R.string.progress_certifying_master_key, 20, 100); - for (String delID : deletedIDs) { + for (String delID : saveParcel.deletedIDs) { masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, delID); } int user_id_index = 0; - if (primaryIDChanged) { + if (saveParcel.primaryIDChanged) { ArrayList> sigList = new ArrayList>(); - for (String userId : userIds) { - String orig_id = OriginalIDs.get(user_id_index); + for (String userId : saveParcel.userIDs) { + String orig_id = saveParcel.originalIDs.get(user_id_index); if (orig_id.equals(userId)) { Iterator orig_sigs = masterPublicKey.getSignaturesForID(orig_id); //TODO: make sure this iterator only has signatures we are interested in while (orig_sigs.hasNext()) { @@ -434,8 +433,8 @@ public class PgpKeyOperation { masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, to_add.first, to_add.second); } } else { - for (String userId : userIds) { - String orig_id = OriginalIDs.get(user_id_index); + for (String userId : saveParcel.userIDs) { + String orig_id = saveParcel.originalIDs.get(user_id_index); if (!orig_id.equals(userId)) { PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) @@ -463,10 +462,10 @@ public class PgpKeyOperation { hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS); hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS); - if (keysExpiryDates.get(0) != null) { + if (saveParcel.keysExpiryDates.get(0) != null) { GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC")); creationDate.setTime(masterPublicKey.getCreationTime()); - GregorianCalendar expiryDate = keysExpiryDates.get(0); + GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(0); //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c //here we purposefully ignore partial days in each date - long type has no fractional part! long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); @@ -490,15 +489,15 @@ public class PgpKeyOperation { PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder( PGPEncryptedData.CAST5, sha1Calc) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - newPassPhrase.toCharArray()); + saveParcel.newPassPhrase.toCharArray()); PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(), unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor); - for (int i = 0; i < keys.size(); ++i) { - updateProgress(40 + 50 * (i - 1) / (keys.size() - 1), 100); - if (new_keys[i]) { + for (int i = 0; i < saveParcel.keys.size(); ++i) { + updateProgress(40 + 50 * (i - 1) / (saveParcel.keys.size() - 1), 100); + if (saveParcel.newKeys[i]) { } else { @@ -506,15 +505,15 @@ public class PgpKeyOperation { } updateProgress(R.string.progress_adding_sub_keys, 40, 100); - for (int i = 1; i < keys.size(); ++i) { - updateProgress(40 + 50 * (i - 1) / (keys.size() - 1), 100); + for (int i = 1; i < saveParcel.keys.size(); ++i) { + updateProgress(40 + 50 * (i - 1) / (saveParcel.keys.size() - 1), 100); - PGPSecretKey subKey = keys.get(i); + PGPSecretKey subKey = saveParcel.keys.get(i); PGPPublicKey subPublicKey = subKey.getPublicKey(); PBESecretKeyDecryptor keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - oldPassPhrase.toCharArray()); + saveParcel.oldPassPhrase.toCharArray()); PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2); // TODO: now used without algorithm and creation time?! (APG 1) @@ -523,7 +522,7 @@ public class PgpKeyOperation { hashedPacketsGen = new PGPSignatureSubpacketGenerator(); unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); - usageId = keysUsages.get(i); + usageId = saveParcel.keysUsages.get(i); canSign = (usageId & KeyFlags.SIGN_DATA) > 0; //todo - separate function for this if (canSign) { Date todayDate = new Date(); //both sig times the same @@ -543,10 +542,10 @@ public class PgpKeyOperation { } hashedPacketsGen.setKeyFlags(false, usageId); - if (keysExpiryDates.get(i) != null) { + if (saveParcel.keysExpiryDates.get(i) != null) { GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC")); creationDate.setTime(subPublicKey.getCreationTime()); - GregorianCalendar expiryDate = keysExpiryDates.get(i); + GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(i); //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c //here we purposefully ignore partial days in each date - long type has no fractional part! long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); @@ -570,7 +569,6 @@ public class PgpKeyOperation { ProviderHelper.saveKeyRing(mContext, publicKeyRing); updateProgress(R.string.progress_done, 100, 100); - */ } public PGPPublicKeyRing certifyKey(long masterKeyId, long pubKeyId, String passphrase) -- cgit v1.2.3 From 6f0a5d39b2931981fb521f533acb5c2c33514734 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Mon, 10 Mar 2014 23:53:28 +0000 Subject: start modifying save code --- .../keychain/pgp/PgpKeyOperation.java | 34 +++++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 87f8fdebb..89be90ab8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -73,6 +73,8 @@ import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; import android.content.Context; import android.util.Pair; +import javax.crypto.SecretKey; + public class PgpKeyOperation { private final Context mContext; private final ProgressDialogUpdater mProgress; @@ -354,6 +356,7 @@ public class PgpKeyOperation { PGPSecretKey masterKey = saveParcel.keys.get(0); PGPSecretKeyRing mKR = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, masterKey.getKeyID()); + PGPPublicKeyRing pKR = ProviderHelper.getPGPPublicKeyRingByKeyId(mContext, masterKey.getKeyID()); if (saveParcel.oldPassPhrase == null) { saveParcel.oldPassPhrase = ""; @@ -497,11 +500,27 @@ public class PgpKeyOperation { for (int i = 0; i < saveParcel.keys.size(); ++i) { updateProgress(40 + 50 * (i - 1) / (saveParcel.keys.size() - 1), 100); - if (saveParcel.newKeys[i]) { - + if (saveParcel.moddedKeys[i]) { +//secretkey.replacepublickey with updated public key +//secretkeyring.insertsecretkey with newly signed secret key } else { - +//else nothing, right? + } + if (saveParcel.newKeys[i]) { + //set the passphrase to the old one, so we can update the whole keyring passphrase later + PBESecretKeyEncryptor keyEncryptorOld = new JcePBESecretKeyEncryptorBuilder( + PGPEncryptedData.CAST5, sha1Calc) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + saveParcel.oldPassPhrase.toCharArray()); + PBESecretKeyDecryptor keyDecryptorBlank = new JcePBESecretKeyDecryptorBuilder() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + saveParcel.oldPassPhrase.toCharArray()); + saveParcel.keys.set(i, PGPSecretKey.copyWithNewPassword(saveParcel.keys.get(i), + keyDecryptorBlank, keyEncryptorOld)); } + //finally, update the keyrings + mKR = PGPSecretKeyRing.insertSecretKey(mKR, saveParcel.keys.get(i)); + pKR = PGPPublicKeyRing.insertPublicKey(pKR, saveParcel.keys.get(i).getPublicKey()); } updateProgress(R.string.progress_adding_sub_keys, 40, 100); @@ -560,13 +579,12 @@ public class PgpKeyOperation { keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate()); } - PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing(); - PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing(); -//must copy with new passphrase... new keys will have an empty passphrase... pass in boolean array to mark new key? + //update the passphrase + mKR = PGPSecretKeyRing.copyWithNewPassword(mKR, keyDecryptor, keyEncryptor); updateProgress(R.string.progress_saving_key_ring, 90, 100); - ProviderHelper.saveKeyRing(mContext, secretKeyRing); - ProviderHelper.saveKeyRing(mContext, publicKeyRing); + ProviderHelper.saveKeyRing(mContext, mKR); + ProviderHelper.saveKeyRing(mContext, pKR); updateProgress(R.string.progress_done, 100, 100); } -- cgit v1.2.3 From fdb013a0529e4fcf3b602f856c0290f5626789aa Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Tue, 11 Mar 2014 00:00:19 +0000 Subject: unused imports --- .../java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 4 ---- 1 file changed, 4 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 89be90ab8..8ef2a7452 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -29,7 +29,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.GregorianCalendar; import java.util.Iterator; -import java.util.List; import java.util.TimeZone; import org.spongycastle.bcpg.CompressionAlgorithmTags; @@ -66,15 +65,12 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; -import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Primes; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; import android.content.Context; import android.util.Pair; -import javax.crypto.SecretKey; - public class PgpKeyOperation { private final Context mContext; private final ProgressDialogUpdater mProgress; -- cgit v1.2.3 From e387dd7c54ddfdbe8379b57e00fed567510fd863 Mon Sep 17 00:00:00 2001 From: uberspot Date: Sat, 15 Mar 2014 01:51:01 +0200 Subject: Fix export for new unified key list #409 --- .../java/org/sufficientlysecure/keychain/Id.java | 1 + .../keychain/helper/ExportHelper.java | 34 ++++++----- .../keychain/pgp/PgpImportExport.java | 69 ++++++++++++---------- .../keychain/service/KeychainIntentService.java | 50 ++++++++-------- .../keychain/ui/EditKeyActivity.java | 6 +- .../keychain/ui/KeyListActivity.java | 5 +- .../keychain/ui/KeyListFragment.java | 18 ++++-- .../keychain/ui/ViewKeyActivity.java | 7 ++- 8 files changed, 111 insertions(+), 79 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java index 1d79edd43..784ec340e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java @@ -119,6 +119,7 @@ public final class Id { public static final int secret_key = 0x21070002; public static final int user_id = 0x21070003; public static final int key = 0x21070004; + public static final int public_secret_key = 0x21070005; } public static final class choice { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java index 557d75dbf..03cf936ee 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java @@ -30,12 +30,18 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; import org.sufficientlysecure.keychain.util.Log; +import java.lang.reflect.Array; +import java.security.Provider; +import java.util.ArrayList; + public class ExportHelper { protected FileDialogFragment mFileDialog; protected String mExportFilename; @@ -62,8 +68,8 @@ public class ExportHelper { /** * Show dialog where to export keys */ - public void showExportKeysDialog(final long[] rowIds, final int keyType, - final String exportFilename) { + public void showExportKeysDialog(final long[] masterKeyIds, final int keyType, + final String exportFilename, final String checkboxString) { mExportFilename = exportFilename; // Message is received after file is selected @@ -72,9 +78,14 @@ public class ExportHelper { public void handleMessage(Message message) { if (message.what == FileDialogFragment.MESSAGE_OKAY) { Bundle data = message.getData(); + int type = keyType; mExportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); - exportKeys(rowIds, keyType); + if( data.getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED) ) { + type = Id.type.public_secret_key; + } + + exportKeys(masterKeyIds, type); } } }; @@ -85,7 +96,7 @@ public class ExportHelper { DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() { public void run() { String title = null; - if (rowIds == null) { + if (masterKeyIds == null) { // export all keys title = mActivity.getString(R.string.title_export_keys); } else { @@ -93,15 +104,10 @@ public class ExportHelper { title = mActivity.getString(R.string.title_export_key); } - String message = null; - if (keyType == Id.type.public_key) { - message = mActivity.getString(R.string.specify_file_to_export_to); - } else { - message = mActivity.getString(R.string.specify_file_to_export_secret_keys_to); - } + String message = mActivity.getString(R.string.specify_file_to_export_to); mFileDialog = FileDialogFragment.newInstance(messenger, title, message, - exportFilename, null); + exportFilename, checkboxString); mFileDialog.show(mActivity.getSupportFragmentManager(), "fileDialog"); } @@ -111,7 +117,7 @@ public class ExportHelper { /** * Export keys */ - public void exportKeys(long[] rowIds, int keyType) { + public void exportKeys(long[] masterKeyIds, int keyType) { Log.d(Constants.TAG, "exportKeys started"); // Send all information needed to service to export key in other thread @@ -125,10 +131,10 @@ public class ExportHelper { data.putString(KeychainIntentService.EXPORT_FILENAME, mExportFilename); data.putInt(KeychainIntentService.EXPORT_KEY_TYPE, keyType); - if (rowIds == null) { + if (masterKeyIds == null) { data.putBoolean(KeychainIntentService.EXPORT_ALL, true); } else { - data.putLongArray(KeychainIntentService.EXPORT_KEY_RING_ROW_ID, rowIds); + data.putLongArray(KeychainIntentService.EXPORT_KEY_RING_MASTER_KEY_ID, masterKeyIds); } intent.putExtra(KeychainIntentService.EXTRA_DATA, data); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index dbfa521e5..0e0fdec83 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.security.Provider; import java.util.ArrayList; import java.util.List; @@ -158,60 +159,68 @@ public class PgpImportExport { return returnData; } - public Bundle exportKeyRings(ArrayList keyRingRowIds, int keyType, + public Bundle exportKeyRings(ArrayList publicKeyRingMasterIds, ArrayList secretKeyRingMasterIds, OutputStream outStream) throws PgpGeneralException, PGPException, IOException { Bundle returnData = new Bundle(); - int rowIdsSize = keyRingRowIds.size(); + int masterKeyIdsSize = publicKeyRingMasterIds.size() + secretKeyRingMasterIds.size(); + int progress = 0; updateProgress( mContext.getResources().getQuantityString(R.plurals.progress_exporting_key, - rowIdsSize), 0, 100); + masterKeyIdsSize), 0, 100); if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { throw new PgpGeneralException( mContext.getString(R.string.error_external_storage_not_ready)); } - // For each row id - for (int i = 0; i < rowIdsSize; ++i) { + // For each public masterKey id + for (long pubKeyMasterId : publicKeyRingMasterIds) { + progress++; // Create an output stream ArmoredOutputStream arOutStream = new ArmoredOutputStream(outStream); arOutStream.setHeader("Version", PgpHelper.getFullVersion(mContext)); - // If the keyType is secret get the PGPSecretKeyRing - // based on the row id and encode it to the output - if (keyType == Id.type.secret_key) { - updateProgress(i * 100 / rowIdsSize / 2, 100); - PGPSecretKeyRing secretKeyRing = - ProviderHelper.getPGPSecretKeyRingByRowId(mContext, keyRingRowIds.get(i)); + updateProgress(progress * 100 / masterKeyIdsSize, 100); + PGPPublicKeyRing publicKeyRing = + ProviderHelper.getPGPPublicKeyRingByMasterKeyId(mContext, pubKeyMasterId); - if (secretKeyRing != null) { - secretKeyRing.encode(arOutStream); - } - if (mKeychainServiceListener.hasServiceStopped()) { - arOutStream.close(); - return null; - } - } else { - updateProgress(i * 100 / rowIdsSize, 100); - PGPPublicKeyRing publicKeyRing = - ProviderHelper.getPGPPublicKeyRingByRowId(mContext, keyRingRowIds.get(i)); + if (publicKeyRing != null) { + publicKeyRing.encode(arOutStream); + } - if (publicKeyRing != null) { - publicKeyRing.encode(arOutStream); - } + if (mKeychainServiceListener.hasServiceStopped()) { + arOutStream.close(); + return null; + } - if (mKeychainServiceListener.hasServiceStopped()) { - arOutStream.close(); - return null; - } + arOutStream.close(); + } + + // For each secret masterKey id + for (long secretKeyMasterId : secretKeyRingMasterIds) { + progress++; + // Create an output stream + ArmoredOutputStream arOutStream = new ArmoredOutputStream(outStream); + arOutStream.setHeader("Version", PgpHelper.getFullVersion(mContext)); + + updateProgress(progress * 100 / masterKeyIdsSize, 100); + PGPSecretKeyRing secretKeyRing = + ProviderHelper.getPGPSecretKeyRingByMasterKeyId(mContext, secretKeyMasterId); + + if (secretKeyRing != null) { + secretKeyRing.encode(arOutStream); + } + if (mKeychainServiceListener.hasServiceStopped()) { + arOutStream.close(); + return null; } arOutStream.close(); } - returnData.putInt(KeychainIntentService.RESULT_EXPORT, rowIdsSize); + returnData.putInt(KeychainIntentService.RESULT_EXPORT, masterKeyIdsSize); updateProgress(R.string.progress_done, 100, 100); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 4e5812202..a44b121ec 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -131,7 +131,6 @@ public class KeychainIntentService extends IntentService public static final String EXPORT_KEY_TYPE = "export_key_type"; public static final String EXPORT_ALL = "export_all"; public static final String EXPORT_KEY_RING_MASTER_KEY_ID = "export_key_ring_id"; - public static final String EXPORT_KEY_RING_ROW_ID = "export_key_rind_row_id"; // upload key public static final String UPLOAD_KEY_SERVER = "upload_key_server"; @@ -660,16 +659,11 @@ public class KeychainIntentService extends IntentService if (data.containsKey(EXPORT_KEY_TYPE)) { keyType = data.getInt(EXPORT_KEY_TYPE); } - + long[] masterKeyIds = data.getLongArray(EXPORT_KEY_RING_MASTER_KEY_ID); String outputFile = data.getString(EXPORT_FILENAME); - long[] rowIds = new long[0]; - - // If not exporting all keys get the rowIds of the keys to export from the intent + // If not exporting all keys get the masterKeyIds of the keys to export from the intent boolean exportAll = data.getBoolean(EXPORT_ALL); - if (!exportAll) { - rowIds = data.getLongArray(EXPORT_KEY_RING_ROW_ID); - } /* Operation */ @@ -678,30 +672,38 @@ public class KeychainIntentService extends IntentService throw new PgpGeneralException(getString(R.string.error_external_storage_not_ready)); } - // OutputStream - FileOutputStream outStream = new FileOutputStream(outputFile); + ArrayList publicMasterKeyIds = new ArrayList(); + ArrayList secretMasterKeyIds = new ArrayList(); + ArrayList allPublicMasterKeyIds = ProviderHelper.getPublicKeyRingsMasterKeyIds(this); + ArrayList allSecretMasterKeyIds = ProviderHelper.getSecretKeyRingsMasterKeyIds(this); - ArrayList keyRingRowIds = new ArrayList(); if (exportAll) { - - // get all key ring row ids based on export type - if (keyType == Id.type.public_key) { - keyRingRowIds = ProviderHelper.getPublicKeyRingsRowIds(this); - } else { - keyRingRowIds = ProviderHelper.getSecretKeyRingsRowIds(this); + // get all public key ring MasterKey ids + if (keyType == Id.type.public_key || keyType == Id.type.public_secret_key) { + publicMasterKeyIds = allPublicMasterKeyIds; + } + // get all secret key ring MasterKey ids + if (keyType == Id.type.secret_key || keyType == Id.type.public_secret_key) { + secretMasterKeyIds = allSecretMasterKeyIds; } } else { - for (long rowId : rowIds) { - keyRingRowIds.add(rowId); + + for (long masterKeyId : masterKeyIds) { + if ((keyType == Id.type.public_key || keyType == Id.type.public_secret_key) + && allPublicMasterKeyIds.contains(masterKeyId)) { + publicMasterKeyIds.add(masterKeyId); + } + if ((keyType == Id.type.secret_key || keyType == Id.type.public_secret_key) + && allSecretMasterKeyIds.contains(masterKeyId)) { + secretMasterKeyIds.add(masterKeyId); + } } } - Bundle resultData; - PgpImportExport pgpImportExport = new PgpImportExport(this, this, this); - - resultData = pgpImportExport - .exportKeyRings(keyRingRowIds, keyType, outStream); + Bundle resultData = pgpImportExport + .exportKeyRings(publicMasterKeyIds, secretMasterKeyIds, + new FileOutputStream(outputFile)); if (mIsCanceled) { boolean isDeleted = new File(outputFile).delete(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index edf980773..7edb61b09 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -322,8 +322,10 @@ public class EditKeyActivity extends ActionBarActivity { cancelClicked(); return true; case R.id.menu_key_edit_export_file: - long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())}; - mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC); + long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri); + long[] ids = new long[]{masterKeyId}; + mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC, + null); return true; case R.id.menu_key_edit_delete: { // Message is received after key is deleted diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java index 078b998e1..5ff4dbdeb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java @@ -58,8 +58,7 @@ public class KeyListActivity extends DrawerActivity { return true; case R.id.menu_key_list_export: - // TODO fix this for unified keylist - mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB); + mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB, null); return true; case R.id.menu_key_list_create: @@ -71,7 +70,7 @@ public class KeyListActivity extends DrawerActivity { return true; case R.id.menu_key_list_secret_export: - mExportHelper.showExportKeysDialog(null, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC); + mExportHelper.showExportKeysDialog(null, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC, null); return true; default: diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 5ac59965d..cac8b7046 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -49,6 +49,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyTypes; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.provider.KeychainDatabase; +import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.HighlightQueryCursorAdapter; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.util.Log; @@ -183,13 +184,22 @@ public class KeyListFragment extends Fragment break; } case R.id.menu_key_list_multi_export: { - // todo: public/secret needs to be handled differently here ids = mStickyList.getWrappedList().getCheckedItemIds(); + long[] masterKeyIds = new long[2*ids.length]; + ArrayList allPubRowIds = + ProviderHelper.getPublicKeyRingsRowIds(getActivity()); + for (int i = 0; i < ids.length; i++) { + if (allPubRowIds.contains(ids[i])) { + masterKeyIds[i] = ProviderHelper.getPublicMasterKeyId(getActivity(), ids[i]); + } else { + masterKeyIds[i] = ProviderHelper.getSecretMasterKeyId(getActivity(), ids[i]); + } + } ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity()); mExportHelper - .showExportKeysDialog(ids, - Id.type.public_key, - Constants.Path.APP_DIR_FILE_PUB); + .showExportKeysDialog(masterKeyIds, Id.type.public_key, + Constants.Path.APP_DIR_FILE_PUB, + getString(R.string.also_export_secret_keys)); break; } case R.id.menu_key_list_multi_select_all: { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 93bb83003..c4097403c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -124,8 +124,11 @@ public class ViewKeyActivity extends ActionBarActivity { uploadToKeyserver(mDataUri); return true; case R.id.menu_key_view_export_file: - long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())}; - mExportHelper.showExportKeysDialog(ids, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB); + long masterKeyId = + ProviderHelper.getPublicMasterKeyId(this, Long.valueOf(mDataUri.getLastPathSegment())); + long[] ids = new long[]{masterKeyId}; + mExportHelper.showExportKeysDialog(ids, Id.type.public_key, + Constants.Path.APP_DIR_FILE_PUB, null); return true; case R.id.menu_key_view_share_default_fingerprint: shareKey(mDataUri, true); -- cgit v1.2.3 From 207010dd86c11db2db04f426d434b68784baacbe Mon Sep 17 00:00:00 2001 From: gogowitczak Date: Sat, 15 Mar 2014 21:16:34 +0100 Subject: Keyserver query now uses machine readable output for search and get. Added separate function for converting algorithm integer ID to String. --- .../keychain/pgp/PgpKeyHelper.java | 4 +- .../keychain/ui/adapter/ImportKeysListEntry.java | 45 +++-- .../keychain/util/HkpKeyServer.java | 193 +++++++++++++-------- 3 files changed, 150 insertions(+), 92 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index 436c26700..b93c68677 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -477,7 +477,7 @@ public class PgpKeyHelper { * @return */ public static String convertKeyIdToHex(long keyId) { - return "0x" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId); + return "0x" + ((keyId >> 32) > 0 ? convertKeyIdToHex32bit(keyId >> 32) : "") + convertKeyIdToHex32bit(keyId); } private static String convertKeyIdToHex32bit(long keyId) { @@ -498,7 +498,7 @@ public class PgpKeyHelper { int len = hexString.length(); String s2 = hexString.substring(len - 8); String s1 = hexString.substring(0, len - 8); - return (Long.parseLong(s1, 16) << 32) | Long.parseLong(s2, 16); + return ((!s1.isEmpty() ? Long.parseLong(s1, 16) << 32 : 0) | Long.parseLong(s2, 16)); } /** diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java index 19f0d1eaf..13309435d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui.adapter; import android.os.Parcel; import android.os.Parcelable; +import android.util.SparseArray; import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPSecretKeyRing; @@ -171,20 +172,34 @@ public class ImportKeysListEntry implements Serializable, Parcelable { .getFingerprint(), true); this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId); this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength(); - int algorithm = pgpKeyRing.getPublicKey().getAlgorithm(); - if (algorithm == PGPPublicKey.RSA_ENCRYPT || algorithm == PGPPublicKey.RSA_GENERAL - || algorithm == PGPPublicKey.RSA_SIGN) { - this.algorithm = "RSA"; - } else if (algorithm == PGPPublicKey.DSA) { - this.algorithm = "DSA"; - } else if (algorithm == PGPPublicKey.ELGAMAL_ENCRYPT - || algorithm == PGPPublicKey.ELGAMAL_GENERAL) { - this.algorithm = "ElGamal"; - } else if (algorithm == PGPPublicKey.EC || algorithm == PGPPublicKey.ECDSA) { - this.algorithm = "ECC"; - } else { - // TODO: with resources - this.algorithm = "unknown"; - } + final int algorithm = pgpKeyRing.getPublicKey().getAlgorithm(); + this.algorithm = getAlgorithmFromId(algorithm); } + + /** + * Based on OpenPGP Message Format + */ + private final static SparseArray ALGORITHM_IDS = new SparseArray() {{ + put(-1, "unknown"); // TODO: with resources + put(0, "unencrypted"); + put(PGPPublicKey.RSA_GENERAL, "RSA"); + put(PGPPublicKey.RSA_ENCRYPT, "RSA"); + put(PGPPublicKey.RSA_SIGN, "RSA"); + put(PGPPublicKey.ELGAMAL_ENCRYPT, "ElGamal"); + put(PGPPublicKey.ELGAMAL_GENERAL, "ElGamal"); + put(PGPPublicKey.DSA, "DSA"); + put(PGPPublicKey.EC, "ECC"); + put(PGPPublicKey.ECDSA, "ECC"); + put(PGPPublicKey.ECDH, "ECC"); + }}; + + /** + * Based on OpenPGP Message Format + */ + public static String getAlgorithmFromId(int algorithmId) { + return (ALGORITHM_IDS.get(algorithmId) != null ? ALGORITHM_IDS.get(algorithmId) : ALGORITHM_IDS.get(-1)); + } + } + + diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index 42fb03a3e..7ec532f5b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -43,6 +43,8 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry.getAlgorithmFromId; + /** * TODO: * rewrite to use machine readable output. @@ -74,16 +76,55 @@ public class HkpKeyServer extends KeyServer { private String mHost; private short mPort; - // example: - // pub 2048R/9F5C9090 2009-08-17 Jörg Runge - // <joerg@joergrunge.de> - public static final Pattern PUB_KEY_LINE = Pattern - .compile( - "pub +([0-9]+)([a-z]+)/.*?0x([0-9a-z]+).*? +([0-9-]+) +(.+)[\n\r]+((?: +.+[\n\r]+)*)", - Pattern.CASE_INSENSITIVE); - public static final Pattern USER_ID_LINE = Pattern.compile("^ +(.+)$", Pattern.MULTILINE - | Pattern.CASE_INSENSITIVE); + /** + * pub:%keyid%:%algo%:%keylen%:%creationdate%:%expirationdate%:%flags% + *
    + *
  • %keyid% = this is either the fingerprint or the key ID of the key. + * Either the 16-digit or 8-digit key IDs are acceptable, but obviously the fingerprint is best.
  • + *
  • %algo% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc). See RFC-2440
  • + *
  • %keylen% = the key length (i.e. 1024, 2048, 4096, etc.)
  • + *
  • %creationdate% = creation date of the key in standard RFC-2440 form (i.e. number of seconds since 1/1/1970 UTC time)
  • + *
  • %expirationdate% = expiration date of the key in standard RFC-2440 form (i.e. number of seconds since 1/1/1970 UTC time)
  • + *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any order. The + * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so + * the absence of a given flag does not necessarily mean the absence of the detail. + *
      + *
    • r == revoked
    • + *
    • d == disabled
    • + *
    • e == expired
    • + *
    + *
  • + *
+ * + * + * @see 5.2. Machine Readable Indexes in Internet-Draft OpenPGP HTTP Keyserver Protocol Document + */ + public static final Pattern PUB_KEY_LINE = Pattern + .compile("pub:([0-9a-fA-F]+):([0-9]+):([0-9]+):([0-9]+):([0-9]*):([rde]*)[ \n\r]*" // pub line + + "(uid:(.*):([0-9]+):([0-9]*):([rde]*))+", // one or more uid lines + Pattern.CASE_INSENSITIVE); + + /** + * uid:%escaped uid string%:%creationdate%:%expirationdate%:%flags% + *
    + *
  • %escaped uid string% = the user ID string, with HTTP %-escaping for anything that isn't 7-bit + * safe as well as for the ":" character. Any other characters may be escaped, as desired.
  • + *
  • %creationdate% = creation date of the key in standard RFC-2440 form (i.e. number of seconds since 1/1/1970 UTC time)
  • + *
  • %expirationdate% = expiration date of the key in standard RFC-2440 form (i.e. number of seconds since 1/1/1970 UTC time)
  • + *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any order. The + * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so + * the absence of a given flag does not necessarily mean the absence of the detail. + *
      + *
    • r == revoked
    • + *
    • d == disabled
    • + *
    • e == expired
    • + *
    + *
  • + *
+ */ + public static final Pattern UID_LINE = Pattern + .compile("uid:(.*):([0-9]+):([0-9]*):([rde]*)", + Pattern.CASE_INSENSITIVE); private static final short PORT_DEFAULT = 11371; @@ -158,82 +199,84 @@ public class HkpKeyServer extends KeyServer { throw new QueryException("querying server(s) for '" + mHost + "' failed"); } - @Override - public ArrayList search(String query) throws QueryException, TooManyResponses, - InsufficientQuery { - ArrayList results = new ArrayList(); + @Override + public ArrayList search(String query) throws QueryException, TooManyResponses, + InsufficientQuery { + ArrayList results = new ArrayList(); - if (query.length() < 3) { - throw new InsufficientQuery(); - } + if (query.length() < 3) { + throw new InsufficientQuery(); + } - String encodedQuery; - try { - encodedQuery = URLEncoder.encode(query, "utf8"); - } catch (UnsupportedEncodingException e) { - return null; - } - String request = "/pks/lookup?op=index&search=" + encodedQuery; + String encodedQuery; + try { + encodedQuery = URLEncoder.encode(query, "utf8"); + } catch (UnsupportedEncodingException e) { + return null; + } + String request = "/pks/lookup?op=index&search=" + encodedQuery + "&options=mr"; - String data = null; - try { - data = query(request); - } catch (HttpError e) { - if (e.getCode() == 404) { - return results; - } else { - if (e.getData().toLowerCase(Locale.US).contains("no keys found")) { - return results; - } else if (e.getData().toLowerCase(Locale.US).contains("too many")) { - throw new TooManyResponses(); - } else if (e.getData().toLowerCase(Locale.US).contains("insufficient")) { - throw new InsufficientQuery(); - } - } - throw new QueryException("querying server(s) for '" + mHost + "' failed"); - } + String data = null; + try { + data = query(request); + } catch (HttpError e) { + if (e.getCode() == 404) { + return results; + } else { + if (e.getData().toLowerCase(Locale.US).contains("no keys found")) { + return results; + } else if (e.getData().toLowerCase(Locale.US).contains("too many")) { + throw new TooManyResponses(); + } else if (e.getData().toLowerCase(Locale.US).contains("insufficient")) { + throw new InsufficientQuery(); + } + } + throw new QueryException("querying server(s) for '" + mHost + "' failed"); + } - Matcher matcher = PUB_KEY_LINE.matcher(data); - while (matcher.find()) { - ImportKeysListEntry info = new ImportKeysListEntry(); - info.bitStrength = Integer.parseInt(matcher.group(1)); - info.algorithm = matcher.group(2); - info.hexKeyId = "0x" + matcher.group(3); - info.keyId = PgpKeyHelper.convertHexToKeyId(matcher.group(3)); - String chunks[] = matcher.group(4).split("-"); - - GregorianCalendar tmpGreg = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - tmpGreg.set(Integer.parseInt(chunks[0]), Integer.parseInt(chunks[1]), - Integer.parseInt(chunks[2])); - info.date = tmpGreg.getTime(); - info.userIds = new ArrayList(); - if (matcher.group(5).startsWith("*** KEY")) { - info.revoked = true; - } else { - String tmp = matcher.group(5).replaceAll("<.*?>", ""); - tmp = Html.fromHtml(tmp).toString(); - info.userIds.add(tmp); - } - if (matcher.group(6).length() > 0) { - Matcher matcher2 = USER_ID_LINE.matcher(matcher.group(6)); - while (matcher2.find()) { - String tmp = matcher2.group(1).replaceAll("<.*?>", ""); - tmp = Html.fromHtml(tmp).toString(); - info.userIds.add(tmp); - } - } - results.add(info); - } + final Matcher matcher = PUB_KEY_LINE.matcher(data); + while (matcher.find()) { + final ImportKeysListEntry info = new ImportKeysListEntry(); + info.bitStrength = Integer.parseInt(matcher.group(3)); + final int algorithmId = Integer.decode(matcher.group(2)); + info.algorithm = getAlgorithmFromId(algorithmId); - return results; - } + info.hexKeyId = "0x" + matcher.group(1); + info.keyId = PgpKeyHelper.convertHexToKeyId(matcher.group(1)); + + final long creationDate = Long.parseLong(matcher.group(4)); + final GregorianCalendar tmpGreg = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + tmpGreg.setTimeInMillis(creationDate*1000); + info.date = tmpGreg.getTime(); + + info.revoked = matcher.group(6).contains("r"); + info.userIds = new ArrayList(); + + final String uidLines = matcher.group(7); + final Matcher uidMatcher = UID_LINE.matcher(uidLines); + while (uidMatcher.find()) { + String tmp = uidMatcher.group(1).replaceAll("<.*?>", ""); + tmp = Html.fromHtml(tmp).toString().trim(); + if (tmp.contains("%")) + { + try { + tmp = (URLDecoder.decode(tmp, "UTF8")); // converts String like "Universit%C3%A4t" to a proper form "Universität". + } catch (UnsupportedEncodingException ignored) { + } + } + info.userIds.add(tmp); + } + results.add(info); + } + return results; + } @Override public String get(long keyId) throws QueryException { HttpClient client = new DefaultHttpClient(); try { HttpGet get = new HttpGet("http://" + mHost + ":" + mPort - + "/pks/lookup?op=get&search=" + PgpKeyHelper.convertKeyIdToHex(keyId)); + + "/pks/lookup?op=get&search=" + PgpKeyHelper.convertKeyIdToHex(keyId) + "&options=mr"); HttpResponse response = client.execute(get); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { -- cgit v1.2.3 From 5277e4c1e76e185132716b0a807066c5abbf340c Mon Sep 17 00:00:00 2001 From: gogowitczak Date: Sat, 15 Mar 2014 22:01:37 +0100 Subject: removed TODO comment --- .../java/org/sufficientlysecure/keychain/util/HkpKeyServer.java | 7 ------- 1 file changed, 7 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index 7ec532f5b..0839fc494 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -45,13 +45,6 @@ import java.util.regex.Pattern; import static org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry.getAlgorithmFromId; -/** - * TODO: - * rewrite to use machine readable output. - *

- * see http://tools.ietf.org/html/draft-shaw-openpgp-hkp-00#section-5 - * https://github.com/openpgp-keychain/openpgp-keychain/issues/259 - */ public class HkpKeyServer extends KeyServer { private static class HttpError extends Exception { private static final long serialVersionUID = 1718783705229428893L; -- cgit v1.2.3 From cea62b1857a9b5dbade8dcff6009f72e309b7469 Mon Sep 17 00:00:00 2001 From: uberspot Date: Sun, 16 Mar 2014 23:35:14 +0200 Subject: Lock drawer as open in tablets --- .../keychain/helper/ActionBarHelper.java | 1 - .../keychain/ui/DrawerActivity.java | 86 +++++++++++++++------- .../keychain/ui/KeyListActivity.java | 3 + 3 files changed, 64 insertions(+), 26 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java index 91e50637e..a26df556d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java @@ -37,7 +37,6 @@ public class ActionBarHelper { * @param activity */ public static void setBackButton(ActionBarActivity activity) { - // set actionbar without home button if called from another app final ActionBar actionBar = activity.getSupportActionBar(); Log.d(Constants.TAG, "calling package (only set when using startActivityForResult)=" + activity.getCallingPackage()); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java index c0fd53007..985f6c309 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java @@ -21,18 +21,17 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; +import android.graphics.Color; import android.os.Bundle; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarActivity; import android.view.*; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.ListView; -import android.widget.TextView; +import android.widget.*; import com.beardedhen.androidbootstrap.FontAwesomeText; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity; public class DrawerActivity extends ActionBarActivity { @@ -42,6 +41,7 @@ public class DrawerActivity extends ActionBarActivity { private CharSequence mDrawerTitle; private CharSequence mTitle; + private boolean mIsDrawerLocked = false; private static Class[] mItemsClass = new Class[]{KeyListActivity.class, EncryptActivity.class, DecryptActivity.class, ImportKeysActivity.class, @@ -55,10 +55,22 @@ public class DrawerActivity extends ActionBarActivity { mDrawerTitle = getString(R.string.app_name); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList = (ListView) findViewById(R.id.left_drawer); - - // set a custom shadow that overlays the main content when the drawer - // opens - mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); + ViewGroup viewGroup = (ViewGroup) findViewById(R.id.content_frame); + int leftMarginLoaded = ((ViewGroup.MarginLayoutParams) viewGroup.getLayoutParams()).leftMargin; + int leftMarginInTablets = (int) getResources().getDimension(R.dimen.drawer_size); + int errorInMarginAllowed = 5; + + // if the left margin of the loaded layout is close to the + // one used in tablets then set drawer as open and locked + if( Math.abs(leftMarginLoaded - leftMarginInTablets) < errorInMarginAllowed) { + mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, mDrawerList); + mDrawerLayout.setScrimColor(Color.TRANSPARENT); + mIsDrawerLocked = true; + } else { + // set a custom shadow that overlays the main content when the drawer opens + mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); + mIsDrawerLocked = false; + } NavItem mItemIconTexts[] = new NavItem[]{ new NavItem("fa-user", getString(R.string.nav_contacts)), @@ -73,8 +85,11 @@ public class DrawerActivity extends ActionBarActivity { mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); // enable ActionBar app icon to behave as action to toggle nav drawer - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setHomeButtonEnabled(true); + // if the drawer is not locked + if ( !mIsDrawerLocked ) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeButtonEnabled(true); + } // ActionBarDrawerToggle ties together the the proper interactions // between the sliding drawer and the action bar app icon @@ -86,19 +101,8 @@ public class DrawerActivity extends ActionBarActivity { ) { public void onDrawerClosed(View view) { getSupportActionBar().setTitle(mTitle); - // creates call to onPrepareOptionsMenu() - supportInvalidateOptionsMenu(); - // call intent activity if selected - if (mSelectedItem != null) { - finish(); - overridePendingTransition(0, 0); - - Intent intent = new Intent(DrawerActivity.this, mSelectedItem); - startActivity(intent); - // disable animation of activity start - overridePendingTransition(0, 0); - } + callIntentForSelectedItem(); } public void onDrawerOpened(View drawerView) { @@ -108,13 +112,37 @@ public class DrawerActivity extends ActionBarActivity { supportInvalidateOptionsMenu(); } }; - mDrawerLayout.setDrawerListener(mDrawerToggle); + if ( !mIsDrawerLocked ) { + mDrawerLayout.setDrawerListener(mDrawerToggle); + } + if ( mIsDrawerLocked ) { + // If the drawer is locked open make it un-focusable + // so that it doesn't consume all the Back button presses + mDrawerLayout.setFocusableInTouchMode(false); + } // if (savedInstanceState == null) { // selectItem(0); // } } + private void callIntentForSelectedItem() { + // creates call to onPrepareOptionsMenu() + supportInvalidateOptionsMenu(); + + // call intent activity if selected + if (mSelectedItem != null) { + finish(); + overridePendingTransition(0, 0); + + Intent intent = new Intent(this, mSelectedItem); + startActivity(intent); + + // disable animation of activity start + overridePendingTransition(0, 0); + } + } + @Override public boolean onCreateOptionsMenu(Menu menu) { menu.add(42, MENU_ID_PREFERENCE, 100, R.string.menu_preferences); @@ -185,10 +213,18 @@ public class DrawerActivity extends ActionBarActivity { private void selectItem(int position) { // update selected item and title, then close the drawer mDrawerList.setItemChecked(position, true); - // setTitle(mDrawerTitles[position]); - mDrawerLayout.closeDrawer(mDrawerList); // set selected class mSelectedItem = mItemsClass[position]; + + // setTitle(mDrawerTitles[position]); + // If drawer isn't locked just close the drawer and + // it will move to the selected item by itself (via drawer toggle listener) + if ( !mIsDrawerLocked ) { + mDrawerLayout.closeDrawer(mDrawerList); + // else move to the selected item yourself + } else { + callIntentForSelectedItem(); + } } /** diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java index 5ff4dbdeb..57709350e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java @@ -53,8 +53,11 @@ public class KeyListActivity extends DrawerActivity { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_key_list_import: + + overridePendingTransition(0, 0); Intent intentImport = new Intent(this, ImportKeysActivity.class); startActivityForResult(intentImport, 0); + overridePendingTransition(0, 0); return true; case R.id.menu_key_list_export: -- cgit v1.2.3 From e01c99a193528df717d5cf5bd9fe20c649297375 Mon Sep 17 00:00:00 2001 From: uberspot Date: Mon, 17 Mar 2014 00:27:52 +0200 Subject: make loading of drawer items a bit more dynamic --- .../org/sufficientlysecure/keychain/Constants.java | 14 +++++++++++ .../keychain/ui/DrawerActivity.java | 27 +++++++++++----------- .../keychain/ui/KeyListActivity.java | 6 +---- 3 files changed, 28 insertions(+), 19 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 011cd9663..ff4abe56a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -19,6 +19,11 @@ package org.sufficientlysecure.keychain; import android.os.Environment; import org.spongycastle.jce.provider.BouncyCastleProvider; +import org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity; +import org.sufficientlysecure.keychain.ui.DecryptActivity; +import org.sufficientlysecure.keychain.ui.EncryptActivity; +import org.sufficientlysecure.keychain.ui.ImportKeysActivity; +import org.sufficientlysecure.keychain.ui.KeyListActivity; public final class Constants { @@ -63,4 +68,13 @@ public final class Constants { public static final String KEY_SERVERS = "pool.sks-keyservers.net, subkeys.pgp.net, pgp.mit.edu"; } + public static final class DrawerItems { + public static final Class KEY_LIST = KeyListActivity.class; + public static final Class ENCRYPT = EncryptActivity.class; + public static final Class DECRYPT = DecryptActivity.class; + public static final Class IMPORT_KEYS = ImportKeysActivity.class; + public static final Class REGISTERED_APPS_LIST = RegisteredAppsListActivity.class; + public static final Class[] ARRAY = new Class[]{KEY_LIST, ENCRYPT, DECRYPT, + IMPORT_KEYS, REGISTERED_APPS_LIST}; + } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java index 985f6c309..f01e67449 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java @@ -30,9 +30,8 @@ import android.support.v7.app.ActionBarActivity; import android.view.*; import android.widget.*; import com.beardedhen.androidbootstrap.FontAwesomeText; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.ActionBarHelper; -import org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity; public class DrawerActivity extends ActionBarActivity { private DrawerLayout mDrawerLayout; @@ -43,9 +42,6 @@ public class DrawerActivity extends ActionBarActivity { private CharSequence mTitle; private boolean mIsDrawerLocked = false; - private static Class[] mItemsClass = new Class[]{KeyListActivity.class, - EncryptActivity.class, DecryptActivity.class, ImportKeysActivity.class, - RegisteredAppsListActivity.class}; private Class mSelectedItem; private static final int MENU_ID_PREFERENCE = 222; @@ -102,7 +98,7 @@ public class DrawerActivity extends ActionBarActivity { public void onDrawerClosed(View view) { getSupportActionBar().setTitle(mTitle); - callIntentForSelectedItem(); + callIntentForDrawerItem(mSelectedItem); } public void onDrawerOpened(View drawerView) { @@ -112,11 +108,10 @@ public class DrawerActivity extends ActionBarActivity { supportInvalidateOptionsMenu(); } }; + if ( !mIsDrawerLocked ) { mDrawerLayout.setDrawerListener(mDrawerToggle); - } - - if ( mIsDrawerLocked ) { + } else { // If the drawer is locked open make it un-focusable // so that it doesn't consume all the Back button presses mDrawerLayout.setFocusableInTouchMode(false); @@ -126,16 +121,20 @@ public class DrawerActivity extends ActionBarActivity { // } } - private void callIntentForSelectedItem() { + /** + * Uses startActivity to call the Intent of the given class + * @param drawerItem the class of the drawer item you want to load. Based on Constants.DrawerItems.* + */ + public void callIntentForDrawerItem(Class drawerItem) { // creates call to onPrepareOptionsMenu() supportInvalidateOptionsMenu(); // call intent activity if selected - if (mSelectedItem != null) { + if (drawerItem != null) { finish(); overridePendingTransition(0, 0); - Intent intent = new Intent(this, mSelectedItem); + Intent intent = new Intent(this, drawerItem); startActivity(intent); // disable animation of activity start @@ -214,7 +213,7 @@ public class DrawerActivity extends ActionBarActivity { // update selected item and title, then close the drawer mDrawerList.setItemChecked(position, true); // set selected class - mSelectedItem = mItemsClass[position]; + mSelectedItem = Constants.DrawerItems.ARRAY[position]; // setTitle(mDrawerTitles[position]); // If drawer isn't locked just close the drawer and @@ -223,7 +222,7 @@ public class DrawerActivity extends ActionBarActivity { mDrawerLayout.closeDrawer(mDrawerList); // else move to the selected item yourself } else { - callIntentForSelectedItem(); + callIntentForDrawerItem(mSelectedItem); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java index 57709350e..06df6f12d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java @@ -53,11 +53,7 @@ public class KeyListActivity extends DrawerActivity { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_key_list_import: - - overridePendingTransition(0, 0); - Intent intentImport = new Intent(this, ImportKeysActivity.class); - startActivityForResult(intentImport, 0); - overridePendingTransition(0, 0); + callIntentForDrawerItem(Constants.DrawerItems.IMPORT_KEYS); return true; case R.id.menu_key_list_export: -- cgit v1.2.3 From fee18bd33e56a90f3d0df9d39dc70b3a2bf30132 Mon Sep 17 00:00:00 2001 From: gogowitczak Date: Tue, 18 Mar 2014 15:44:20 +0100 Subject: Fixed coding style. --- .../keychain/ui/adapter/ImportKeysListEntry.java | 49 ++-- .../keychain/util/HkpKeyServer.java | 250 +++++++++++---------- 2 files changed, 153 insertions(+), 146 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java index 13309435d..05521b0c9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java @@ -173,33 +173,30 @@ public class ImportKeysListEntry implements Serializable, Parcelable { this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId); this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength(); final int algorithm = pgpKeyRing.getPublicKey().getAlgorithm(); - this.algorithm = getAlgorithmFromId(algorithm); + this.algorithm = getAlgorithmFromId(algorithm); } - /** - * Based on OpenPGP Message Format - */ - private final static SparseArray ALGORITHM_IDS = new SparseArray() {{ - put(-1, "unknown"); // TODO: with resources - put(0, "unencrypted"); - put(PGPPublicKey.RSA_GENERAL, "RSA"); - put(PGPPublicKey.RSA_ENCRYPT, "RSA"); - put(PGPPublicKey.RSA_SIGN, "RSA"); - put(PGPPublicKey.ELGAMAL_ENCRYPT, "ElGamal"); - put(PGPPublicKey.ELGAMAL_GENERAL, "ElGamal"); - put(PGPPublicKey.DSA, "DSA"); - put(PGPPublicKey.EC, "ECC"); - put(PGPPublicKey.ECDSA, "ECC"); - put(PGPPublicKey.ECDH, "ECC"); - }}; - - /** - * Based on OpenPGP Message Format - */ - public static String getAlgorithmFromId(int algorithmId) { - return (ALGORITHM_IDS.get(algorithmId) != null ? ALGORITHM_IDS.get(algorithmId) : ALGORITHM_IDS.get(-1)); - } + /** + * Based on OpenPGP Message Format + */ + private final static SparseArray ALGORITHM_IDS = new SparseArray() {{ + put(-1, "unknown"); // TODO: with resources + put(0, "unencrypted"); + put(PGPPublicKey.RSA_GENERAL, "RSA"); + put(PGPPublicKey.RSA_ENCRYPT, "RSA"); + put(PGPPublicKey.RSA_SIGN, "RSA"); + put(PGPPublicKey.ELGAMAL_ENCRYPT, "ElGamal"); + put(PGPPublicKey.ELGAMAL_GENERAL, "ElGamal"); + put(PGPPublicKey.DSA, "DSA"); + put(PGPPublicKey.EC, "ECC"); + put(PGPPublicKey.ECDSA, "ECC"); + put(PGPPublicKey.ECDH, "ECC"); + }}; + /** + * Based on OpenPGP Message Format + */ + public static String getAlgorithmFromId(int algorithmId) { + return (ALGORITHM_IDS.get(algorithmId) != null ? ALGORITHM_IDS.get(algorithmId) : ALGORITHM_IDS.get(-1)); + } } - - diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index 0839fc494..a354d19e8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -69,55 +69,64 @@ public class HkpKeyServer extends KeyServer { private String mHost; private short mPort; - /** - * pub:%keyid%:%algo%:%keylen%:%creationdate%:%expirationdate%:%flags% - *

    - *
  • %keyid% = this is either the fingerprint or the key ID of the key. - * Either the 16-digit or 8-digit key IDs are acceptable, but obviously the fingerprint is best.
  • - *
  • %algo% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc). See RFC-2440
  • - *
  • %keylen% = the key length (i.e. 1024, 2048, 4096, etc.)
  • - *
  • %creationdate% = creation date of the key in standard RFC-2440 form (i.e. number of seconds since 1/1/1970 UTC time)
  • - *
  • %expirationdate% = expiration date of the key in standard RFC-2440 form (i.e. number of seconds since 1/1/1970 UTC time)
  • - *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any order. The - * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so - * the absence of a given flag does not necessarily mean the absence of the detail. - *
      - *
    • r == revoked
    • - *
    • d == disabled
    • - *
    • e == expired
    • - *
    - *
  • - *
- * - * - * @see 5.2. Machine Readable Indexes in Internet-Draft OpenPGP HTTP Keyserver Protocol Document - */ - public static final Pattern PUB_KEY_LINE = Pattern - .compile("pub:([0-9a-fA-F]+):([0-9]+):([0-9]+):([0-9]+):([0-9]*):([rde]*)[ \n\r]*" // pub line - + "(uid:(.*):([0-9]+):([0-9]*):([rde]*))+", // one or more uid lines - Pattern.CASE_INSENSITIVE); - - /** - * uid:%escaped uid string%:%creationdate%:%expirationdate%:%flags% - *
    - *
  • %escaped uid string% = the user ID string, with HTTP %-escaping for anything that isn't 7-bit - * safe as well as for the ":" character. Any other characters may be escaped, as desired.
  • - *
  • %creationdate% = creation date of the key in standard RFC-2440 form (i.e. number of seconds since 1/1/1970 UTC time)
  • - *
  • %expirationdate% = expiration date of the key in standard RFC-2440 form (i.e. number of seconds since 1/1/1970 UTC time)
  • - *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any order. The - * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so - * the absence of a given flag does not necessarily mean the absence of the detail. - *
      - *
    • r == revoked
    • - *
    • d == disabled
    • - *
    • e == expired
    • - *
    - *
  • - *
- */ - public static final Pattern UID_LINE = Pattern - .compile("uid:(.*):([0-9]+):([0-9]*):([rde]*)", - Pattern.CASE_INSENSITIVE); + /** + * pub:%keyid%:%algo%:%keylen%:%creationdate%:%expirationdate%:%flags% + *
    + *
  • %keyid% = this is either the fingerprint or the key ID of the key. Either the 16-digit or 8-digit + * key IDs are acceptable, but obviously the fingerprint is best.
  • + *
  • %algo% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc). + * See RFC-2440
  • + *
  • %keylen% = the key length (i.e. 1024, 2048, 4096, etc.)
  • + *
  • %creationdate% = creation date of the key in standard + * RFC-2440 form (i.e. number of seconds since + * 1/1/1970 UTC time)
  • + *
  • %expirationdate% = expiration date of the key in standard + * RFC-2440 form (i.e. number of seconds since + * 1/1/1970 UTC time)
  • + *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any order. The + * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so + * the absence of a given flag does not necessarily mean the absence of the detail. + *
      + *
    • r == revoked
    • + *
    • d == disabled
    • + *
    • e == expired
    • + *
    + *
  • + *
+ * + * @see 5.2. Machine Readable Indexes + * in Internet-Draft OpenPGP HTTP Keyserver Protocol Document + */ + public static final Pattern PUB_KEY_LINE = Pattern + .compile("pub:([0-9a-fA-F]+):([0-9]+):([0-9]+):([0-9]+):([0-9]*):([rde]*)[ \n\r]*" // pub line + + "(uid:(.*):([0-9]+):([0-9]*):([rde]*))+", // one or more uid lines + Pattern.CASE_INSENSITIVE); + + /** + * uid:%escaped uid string%:%creationdate%:%expirationdate%:%flags% + *
    + *
  • %escaped uid string% = the user ID string, with HTTP %-escaping for anything that isn't 7-bit + * safe as well as for the ":" character. Any other characters may be escaped, as desired.
  • + *
  • %creationdate% = creation date of the key in standard + * RFC-2440 form (i.e. number of seconds since + * 1/1/1970 UTC time)
  • + *
  • %expirationdate% = expiration date of the key in standard + * RFC-2440 form (i.e. number of seconds since + * 1/1/1970 UTC time)
  • + *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any order. The + * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so + * the absence of a given flag does not necessarily mean the absence of the detail. + *
      + *
    • r == revoked
    • + *
    • d == disabled
    • + *
    • e == expired
    • + *
    + *
  • + *
+ */ + public static final Pattern UID_LINE = Pattern + .compile("uid:(.*):([0-9]+):([0-9]*):([rde]*)", + Pattern.CASE_INSENSITIVE); private static final short PORT_DEFAULT = 11371; @@ -192,77 +201,78 @@ public class HkpKeyServer extends KeyServer { throw new QueryException("querying server(s) for '" + mHost + "' failed"); } - @Override - public ArrayList search(String query) throws QueryException, TooManyResponses, - InsufficientQuery { - ArrayList results = new ArrayList(); - - if (query.length() < 3) { - throw new InsufficientQuery(); - } - - String encodedQuery; - try { - encodedQuery = URLEncoder.encode(query, "utf8"); - } catch (UnsupportedEncodingException e) { - return null; - } - String request = "/pks/lookup?op=index&search=" + encodedQuery + "&options=mr"; - - String data = null; - try { - data = query(request); - } catch (HttpError e) { - if (e.getCode() == 404) { - return results; - } else { - if (e.getData().toLowerCase(Locale.US).contains("no keys found")) { - return results; - } else if (e.getData().toLowerCase(Locale.US).contains("too many")) { - throw new TooManyResponses(); - } else if (e.getData().toLowerCase(Locale.US).contains("insufficient")) { - throw new InsufficientQuery(); - } - } - throw new QueryException("querying server(s) for '" + mHost + "' failed"); - } - - final Matcher matcher = PUB_KEY_LINE.matcher(data); - while (matcher.find()) { - final ImportKeysListEntry info = new ImportKeysListEntry(); - info.bitStrength = Integer.parseInt(matcher.group(3)); - final int algorithmId = Integer.decode(matcher.group(2)); - info.algorithm = getAlgorithmFromId(algorithmId); - - info.hexKeyId = "0x" + matcher.group(1); - info.keyId = PgpKeyHelper.convertHexToKeyId(matcher.group(1)); - - final long creationDate = Long.parseLong(matcher.group(4)); - final GregorianCalendar tmpGreg = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - tmpGreg.setTimeInMillis(creationDate*1000); - info.date = tmpGreg.getTime(); - - info.revoked = matcher.group(6).contains("r"); - info.userIds = new ArrayList(); - - final String uidLines = matcher.group(7); - final Matcher uidMatcher = UID_LINE.matcher(uidLines); - while (uidMatcher.find()) { - String tmp = uidMatcher.group(1).replaceAll("<.*?>", ""); - tmp = Html.fromHtml(tmp).toString().trim(); - if (tmp.contains("%")) - { - try { - tmp = (URLDecoder.decode(tmp, "UTF8")); // converts String like "Universit%C3%A4t" to a proper form "Universität". - } catch (UnsupportedEncodingException ignored) { - } - } - info.userIds.add(tmp); - } - results.add(info); - } - return results; - } + @Override + public ArrayList search(String query) throws QueryException, TooManyResponses, + InsufficientQuery { + ArrayList results = new ArrayList(); + + if (query.length() < 3) { + throw new InsufficientQuery(); + } + + String encodedQuery; + try { + encodedQuery = URLEncoder.encode(query, "utf8"); + } catch (UnsupportedEncodingException e) { + return null; + } + String request = "/pks/lookup?op=index&search=" + encodedQuery + "&options=mr"; + + String data = null; + try { + data = query(request); + } catch (HttpError e) { + if (e.getCode() == 404) { + return results; + } else { + if (e.getData().toLowerCase(Locale.US).contains("no keys found")) { + return results; + } else if (e.getData().toLowerCase(Locale.US).contains("too many")) { + throw new TooManyResponses(); + } else if (e.getData().toLowerCase(Locale.US).contains("insufficient")) { + throw new InsufficientQuery(); + } + } + throw new QueryException("querying server(s) for '" + mHost + "' failed"); + } + + final Matcher matcher = PUB_KEY_LINE.matcher(data); + while (matcher.find()) { + final ImportKeysListEntry info = new ImportKeysListEntry(); + info.bitStrength = Integer.parseInt(matcher.group(3)); + final int algorithmId = Integer.decode(matcher.group(2)); + info.algorithm = getAlgorithmFromId(algorithmId); + + info.hexKeyId = "0x" + matcher.group(1); + info.keyId = PgpKeyHelper.convertHexToKeyId(matcher.group(1)); + + final long creationDate = Long.parseLong(matcher.group(4)); + final GregorianCalendar tmpGreg = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + tmpGreg.setTimeInMillis(creationDate * 1000); + info.date = tmpGreg.getTime(); + + info.revoked = matcher.group(6).contains("r"); + info.userIds = new ArrayList(); + + final String uidLines = matcher.group(7); + final Matcher uidMatcher = UID_LINE.matcher(uidLines); + while (uidMatcher.find()) { + String tmp = uidMatcher.group(1).replaceAll("<.*?>", ""); + tmp = Html.fromHtml(tmp).toString().trim(); + if (tmp.contains("%")) { + try { + // converts Strings like "Universit%C3%A4t" to a proper encoding form "Universität". + tmp = (URLDecoder.decode(tmp, "UTF8")); + } catch (UnsupportedEncodingException ignored) { + // will never happen, because "UTF8" is supported + } + } + info.userIds.add(tmp); + } + results.add(info); + } + return results; + } @Override public String get(long keyId) throws QueryException { -- cgit v1.2.3 From fa439c1a721320eb6c4bb17532ff96937bbb4a17 Mon Sep 17 00:00:00 2001 From: Sreeram Boyapati Date: Tue, 18 Mar 2014 07:17:05 +0530 Subject: Can_Encrypt Check added to hide Button --- .../java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index eeb17fea2..b2f9c9f40 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -266,7 +266,10 @@ public class ViewKeyMainFragment extends Fragment implements if (data.moveToFirst()) { // get key id from MASTER_KEY_ID long keyId = data.getLong(KEYS_INDEX_KEY_ID); - + long can_encrypt = data.getLong(KEYS_INDEX_CAN_ENCRYPT); + if(can_encrypt == 0){ + mActionEncrypt.setVisibility(View.GONE); + } String keyIdStr = PgpKeyHelper.convertKeyIdToHex(keyId); mKeyId.setText(keyIdStr); -- cgit v1.2.3 From f34b3ee5316b95bbef9c9ac30b753d1708c4dbc4 Mon Sep 17 00:00:00 2001 From: Sreeram Boyapati Date: Tue, 18 Mar 2014 20:40:09 +0530 Subject: Button Text changes to Change Passphrase if Passphrase is set --- .../java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index edf980773..93099427d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -368,9 +368,8 @@ public class EditKeyActivity extends ActionBarActivity { } mCurrentPassphrase = ""; - - buildLayout(); mIsPassPhraseSet = PassphraseCacheService.hasPassphrase(this, masterKeyId); + buildLayout(); if (!mIsPassPhraseSet) { // check "no passphrase" checkbox and remove button mNoPassphrase.setChecked(true); @@ -425,11 +424,14 @@ public class EditKeyActivity extends ActionBarActivity { // find views mChangePassphrase = (BootstrapButton) findViewById(R.id.edit_key_btn_change_passphrase); mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase); - // Build layout based on given userIds and keys + LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout container = (LinearLayout) findViewById(R.id.edit_key_container); + if(mIsPassPhraseSet){ + mChangePassphrase.setText(getString(R.string.btn_change_passphrase)); + } mUserIdsView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); mUserIdsView.setType(Id.type.user_id); mUserIdsView.setCanEdit(mMasterCanSign); -- cgit v1.2.3 From eebf1c171a0ba70a92d76f5affb93476f6813e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 18 Mar 2014 16:29:40 +0100 Subject: add mr option in keyserver class before query (code simplification) --- .../java/org/sufficientlysecure/keychain/util/HkpKeyServer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index a354d19e8..0c07e9b06 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -216,9 +216,9 @@ public class HkpKeyServer extends KeyServer { } catch (UnsupportedEncodingException e) { return null; } - String request = "/pks/lookup?op=index&search=" + encodedQuery + "&options=mr"; + String request = "/pks/lookup?op=index&options=mr&search=" + encodedQuery; - String data = null; + String data; try { data = query(request); } catch (HttpError e) { @@ -279,7 +279,7 @@ public class HkpKeyServer extends KeyServer { HttpClient client = new DefaultHttpClient(); try { HttpGet get = new HttpGet("http://" + mHost + ":" + mPort - + "/pks/lookup?op=get&search=" + PgpKeyHelper.convertKeyIdToHex(keyId) + "&options=mr"); + + "/pks/lookup?op=get&options=mr&search=" + PgpKeyHelper.convertKeyIdToHex(keyId)); HttpResponse response = client.execute(get); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { -- cgit v1.2.3 From 2d3f47eb99c18b188ed6e4f396605d6b0340de16 Mon Sep 17 00:00:00 2001 From: Daniel Hammann Date: Tue, 18 Mar 2014 16:07:17 +0100 Subject: Show revocation status in SelectPublicKeyFragment #375 Added revocation status in Key List View (graphical symbol and red coloring) --- .../sufficientlysecure/keychain/ui/ViewKeyMainFragment.java | 11 ++++++----- .../keychain/ui/adapter/ViewKeyKeysAdapter.java | 13 ++++++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index eeb17fea2..7ff4e0c57 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -192,8 +192,8 @@ public class ViewKeyMainFragment extends Fragment implements KeychainContract.Keys.IS_MASTER_KEY, KeychainContract.Keys.ALGORITHM, KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY, KeychainContract.Keys.CAN_SIGN, KeychainContract.Keys.CAN_ENCRYPT, - KeychainContract.Keys.CREATION, KeychainContract.Keys.EXPIRY, - KeychainContract.Keys.FINGERPRINT}; + KeychainContract.Keys.IS_REVOKED, KeychainContract.Keys.CREATION, + KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT}; static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC"; static final int KEYS_INDEX_ID = 0; static final int KEYS_INDEX_KEY_ID = 1; @@ -203,9 +203,10 @@ public class ViewKeyMainFragment extends Fragment implements static final int KEYS_INDEX_CAN_CERTIFY = 5; static final int KEYS_INDEX_CAN_SIGN = 6; static final int KEYS_INDEX_CAN_ENCRYPT = 7; - static final int KEYS_INDEX_CREATION = 8; - static final int KEYS_INDEX_EXPIRY = 9; - static final int KEYS_INDEX_FINGERPRINT = 10; + static final int KEYS_INDEX_IS_REVOKED = 8; + static final int KEYS_INDEX_CREATION = 9; + static final int KEYS_INDEX_EXPIRY = 10; + static final int KEYS_INDEX_FINGERPRINT = 11; public Loader onCreateLoader(int id, Bundle args) { switch (id) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java index 153a3f266..5f911275d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui.adapter; import android.content.Context; import android.database.Cursor; +import android.graphics.Color; import android.support.v4.widget.CursorAdapter; import android.view.LayoutInflater; import android.view.View; @@ -39,6 +40,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter { private int mIndexCanCertify; private int mIndexCanEncrypt; private int mIndexCanSign; + private int mIndexRevokedKey; public ViewKeyKeysAdapter(Context context, Cursor c, int flags) { super(context, c, flags); @@ -70,6 +72,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter { mIndexCanCertify = cursor.getColumnIndexOrThrow(Keys.CAN_CERTIFY); mIndexCanEncrypt = cursor.getColumnIndexOrThrow(Keys.CAN_ENCRYPT); mIndexCanSign = cursor.getColumnIndexOrThrow(Keys.CAN_SIGN); + mIndexRevokedKey = cursor.getColumnIndexOrThrow(Keys.IS_REVOKED); } } @@ -81,13 +84,13 @@ public class ViewKeyKeysAdapter extends CursorAdapter { ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey); ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey); ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey); + ImageView revokedKeyIcon = (ImageView) view.findViewById(R.id.ic_revokedKey); String keyIdStr = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId)); String algorithmStr = PgpKeyHelper.getAlgorithmInfo(cursor.getInt(mIndexAlgorithm), cursor.getInt(mIndexKeySize)); keyId.setText(keyIdStr); - keyDetails.setText("(" + algorithmStr + ")"); if (cursor.getInt(mIndexIsMasterKey) != 1) { @@ -113,6 +116,14 @@ public class ViewKeyKeysAdapter extends CursorAdapter { } else { signIcon.setVisibility(View.VISIBLE); } + + if (cursor.getInt(mIndexRevokedKey) > 0) { + revokedKeyIcon.setVisibility(View.VISIBLE); + keyId.setTextColor(Color.RED); + keyDetails.setTextColor(Color.RED); + } else { + revokedKeyIcon.setVisibility(View.GONE); + } } @Override -- cgit v1.2.3 From 163e9fddb9f16d50efe2f936c096bcfec1de2117 Mon Sep 17 00:00:00 2001 From: Sreeram Boyapati Date: Tue, 18 Mar 2014 21:10:09 +0530 Subject: Code Style fix --- .../java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index b2f9c9f40..4844c4028 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -266,8 +266,8 @@ public class ViewKeyMainFragment extends Fragment implements if (data.moveToFirst()) { // get key id from MASTER_KEY_ID long keyId = data.getLong(KEYS_INDEX_KEY_ID); - long can_encrypt = data.getLong(KEYS_INDEX_CAN_ENCRYPT); - if(can_encrypt == 0){ + long canEncrypt = data.getLong(KEYS_INDEX_CAN_ENCRYPT); + if(canEncrypt == 0){ mActionEncrypt.setVisibility(View.GONE); } String keyIdStr = PgpKeyHelper.convertKeyIdToHex(keyId); -- cgit v1.2.3 From ea648e5a431e20bf7a49ff7e6f41ae89465db8c1 Mon Sep 17 00:00:00 2001 From: uberspot Date: Tue, 18 Mar 2014 19:24:04 +0200 Subject: fix emails not showing up in import keyserver search --- .../main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index 0c07e9b06..9d6850027 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -257,8 +257,7 @@ public class HkpKeyServer extends KeyServer { final String uidLines = matcher.group(7); final Matcher uidMatcher = UID_LINE.matcher(uidLines); while (uidMatcher.find()) { - String tmp = uidMatcher.group(1).replaceAll("<.*?>", ""); - tmp = Html.fromHtml(tmp).toString().trim(); + String tmp = uidMatcher.group(1).trim(); if (tmp.contains("%")) { try { // converts Strings like "Universit%C3%A4t" to a proper encoding form "Universität". -- cgit v1.2.3 From 4aa24413deaa46fc5a583d6e380231a8ce630e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 18 Mar 2014 18:35:59 +0100 Subject: revert ca_necrypt patch --- .../java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java | 4 ---- 1 file changed, 4 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index 1958d3bb8..e140cb21e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -286,10 +286,6 @@ public class ViewKeyMainFragment extends Fragment implements if (data.moveToFirst()) { // get key id from MASTER_KEY_ID long keyId = data.getLong(KEYS_INDEX_KEY_ID); - long canEncrypt = data.getLong(KEYS_INDEX_CAN_ENCRYPT); - if(canEncrypt == 0){ - mActionEncrypt.setVisibility(View.GONE); - } String keyIdStr = PgpKeyHelper.convertKeyIdToHex(keyId); mKeyId.setText(keyIdStr); -- cgit v1.2.3 From 654c3029610f932d3d3396ce70e4bf2702427b38 Mon Sep 17 00:00:00 2001 From: uberspot Date: Tue, 18 Mar 2014 20:13:33 +0200 Subject: CertifyKeyActivity sets error if no key is selected --- .../sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java index 3d22ca9f6..6b57fc568 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java @@ -119,8 +119,8 @@ public class SelectSecretKeyLayoutFragment extends Fragment { } public void setError(String error) { - mKeyUserId.requestFocus(); - mKeyUserId.setError(error); + mNoKeySelected.requestFocus(); + mNoKeySelected.setError(error); } /** -- cgit v1.2.3 From 9d60224980e33552993baa20e99c656b1203ab55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 18 Mar 2014 19:36:59 +0100 Subject: Cleanup SelectSecretKeyActivity and also return Uri --- .../keychain/ui/SelectSecretKeyActivity.java | 89 +++++----------------- .../keychain/ui/SelectSecretKeyFragment.java | 12 +-- 2 files changed, 26 insertions(+), 75 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java index 1509bc88c..40771b90d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java @@ -1,36 +1,32 @@ /* - * Copyright (C) 2012 Dominik Schürmann - * Copyright (C) 2010 Thialfihar + * Copyright (C) 2012-2014 Dominik Schürmann * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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, either version 3 of the License, or + * (at your option) any later version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package org.sufficientlysecure.keychain.ui; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity; -import android.view.Menu; -import org.sufficientlysecure.keychain.Constants; + import org.sufficientlysecure.keychain.R; public class SelectSecretKeyActivity extends ActionBarActivity { - // Actions for internal use only: - public static final String ACTION_SELECT_SECRET_KEY = Constants.INTENT_PREFIX - + "SELECT_SECRET_KEYRING"; - public static final String EXTRA_FILTER_CERTIFY = "filter_certify"; public static final String RESULT_EXTRA_MASTER_KEY_ID = "master_key_id"; @@ -50,23 +46,8 @@ public class SelectSecretKeyActivity extends ActionBarActivity { actionBar.setDisplayHomeAsUpEnabled(false); actionBar.setHomeButtonEnabled(false); - setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); - - // TODO: reimplement! - // mFilterLayout = findViewById(R.id.layout_filter); - // mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo); - // mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear); - // - // mClearFilterButton.setOnClickListener(new OnClickListener() { - // public void onClick(View v) { - // handleIntent(new Intent()); - // } - // }); - mFilterCertify = getIntent().getBooleanExtra(EXTRA_FILTER_CERTIFY, false); - handleIntent(getIntent()); - // Check that the activity is using the layout version with // the fragment_container FrameLayout if (findViewById(R.id.select_secret_key_fragment_container) != null) { @@ -90,48 +71,18 @@ public class SelectSecretKeyActivity extends ActionBarActivity { /** * This is executed by SelectSecretKeyFragment after clicking on an item * - * @param masterKeyId - * @param userId + * @param selectedUri */ - public void afterListSelection(long masterKeyId, String userId) { + public void afterListSelection(Uri selectedUri) { Intent data = new Intent(); + data.setData(selectedUri); + + // TODO: deprecate RESULT_EXTRA_MASTER_KEY_ID! + long masterKeyId = Long.valueOf(selectedUri.getLastPathSegment()); data.putExtra(RESULT_EXTRA_MASTER_KEY_ID, masterKeyId); - data.putExtra(RESULT_EXTRA_USER_ID, (String) userId); + setResult(RESULT_OK, data); finish(); } - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - handleIntent(intent); - } - - private void handleIntent(Intent intent) { - // TODO: reimplement! - - // String searchString = null; - // if (Intent.ACTION_SEARCH.equals(intent.getAction())) { - // searchString = intent.getStringExtra(SearchManager.QUERY); - // if (searchString != null && searchString.trim().length() == 0) { - // searchString = null; - // } - // } - - // if (searchString == null) { - // mFilterLayout.setVisibility(View.GONE); - // } else { - // mFilterLayout.setVisibility(View.VISIBLE); - // mFilterInfo.setText(getString(R.string.filterInfo, searchString)); - // } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // TODO: reimplement! - // menu.add(0, Id.menu.option.search, 0, R.string.menu_search).setIcon( - // android.R.drawable.ic_menu_search); - return true; - } - } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java index 47a3fbad3..2efa7d33a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Dominik Schürmann + * Copyright (C) 2012-2014 Dominik Schürmann * Copyright (C) 2010 Thialfihar * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,6 +28,7 @@ import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; + import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; @@ -55,10 +56,9 @@ public class SelectSecretKeyFragment extends ListFragment implements */ public static SelectSecretKeyFragment newInstance(boolean filterCertify) { SelectSecretKeyFragment frag = new SelectSecretKeyFragment(); - Bundle args = new Bundle(); + Bundle args = new Bundle(); args.putBoolean(ARG_FILTER_CERTIFY, filterCertify); - frag.setArguments(args); return frag; @@ -85,10 +85,10 @@ public class SelectSecretKeyFragment extends ListFragment implements @Override public void onItemClick(AdapterView adapterView, View view, int position, long id) { long masterKeyId = mAdapter.getMasterKeyId(position); - String userId = mAdapter.getUserId(position); + Uri result = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(masterKeyId)); // return data to activity, which results in finishing it - mActivity.afterListSelection(masterKeyId, userId); + mActivity.afterListSelection(result); } }); @@ -141,7 +141,7 @@ public class SelectSecretKeyFragment extends ListFragment implements + Keys.IS_REVOKED + " = '0' AND valid_keys." + Keys.CAN_SIGN + " = '1' AND valid_keys." + Keys.CREATION + " <= '" + now + "' AND " + "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys." + Keys.EXPIRY - + " >= '" + now + "')) AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, }; + + " >= '" + now + "')) AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID,}; String orderBy = UserIds.USER_ID + " ASC"; -- cgit v1.2.3 From 2435794279bbf8ee8775f4a2629c91827b0a278e Mon Sep 17 00:00:00 2001 From: gogowitczak Date: Tue, 18 Mar 2014 21:52:44 +0100 Subject: Blocked ok button for generating weak (<1024) RSA key. --- .../ui/dialog/CreateKeyDialogFragment.java | 39 +++++++++++++--------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java index a41bc2bee..ffb45afc5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java @@ -25,6 +25,7 @@ import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentActivity; import android.view.LayoutInflater; import android.view.View; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; import org.sufficientlysecure.keychain.Id; @@ -113,21 +114,8 @@ public class CreateKeyDialogFragment extends DialogFragment { public void onClick(DialogInterface di, int id) { di.dismiss(); try { - int nKeyIndex = keySize.getSelectedItemPosition(); - switch (nKeyIndex) { - case 0: - mNewKeySize = 512; - break; - case 1: - mNewKeySize = 1024; - break; - case 2: - mNewKeySize = 2048; - break; - case 3: - mNewKeySize = 4096; - break; - } + final String selectedItem = (String) keySize.getSelectedItem(); + mNewKeySize = Integer.parseInt(selectedItem); } catch (NumberFormatException e) { mNewKeySize = 0; } @@ -145,7 +133,26 @@ public class CreateKeyDialogFragment extends DialogFragment { } }); - return dialog.create(); + final AlertDialog alertDialog = dialog.create(); + + final AdapterView.OnItemSelectedListener weakRsaListener = new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + final Choice selectedAlgorithm = (Choice)algorithm.getSelectedItem(); + final int selectedKeySize = Integer.parseInt((String)keySize.getSelectedItem()); + final boolean isWeakRsa = (selectedAlgorithm.getId() == Id.choice.algorithm.rsa && selectedKeySize <= 1024); + alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(!isWeakRsa); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }; + + keySize.setOnItemSelectedListener(weakRsaListener); + algorithm.setOnItemSelectedListener(weakRsaListener); + + return alertDialog; } } -- cgit v1.2.3 From 69d26496a22dbc341fc9e646c13516626007aa08 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Wed, 19 Mar 2014 03:32:09 +0100 Subject: use correct LongSparseArray for minimum api level --- .../org/sufficientlysecure/keychain/service/PassphraseCacheService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index 176d09c1a..5825db01b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -26,7 +26,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.*; import android.util.Log; -import android.util.LongSparseArray; +import android.support.v4.util.LongSparseArray; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPSecretKey; -- cgit v1.2.3 From 12b97d251a345cbea644c830fb323b90fa24fdbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 19 Mar 2014 16:22:10 +0100 Subject: Cleanup --- .../org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java index 40771b90d..82a3c2e8e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java @@ -30,9 +30,8 @@ public class SelectSecretKeyActivity extends ActionBarActivity { public static final String EXTRA_FILTER_CERTIFY = "filter_certify"; public static final String RESULT_EXTRA_MASTER_KEY_ID = "master_key_id"; - public static final String RESULT_EXTRA_USER_ID = "user_id"; - private boolean mFilterCertify = false; + private boolean mFilterCertify; private SelectSecretKeyFragment mSelectFragment; @Override -- cgit v1.2.3 From 977e76e7e4589162436e2d82978b0d1189d20297 Mon Sep 17 00:00:00 2001 From: uberspot Date: Wed, 19 Mar 2014 18:28:34 +0200 Subject: add apg's fix for Key id display --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java | 6 +++++- .../java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java | 2 +- .../keychain/ui/SelectSecretKeyLayoutFragment.java | 2 +- .../keychain/ui/adapter/SelectKeyCursorAdapter.java | 2 +- .../sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index b93c68677..5b00d163a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -477,7 +477,11 @@ public class PgpKeyHelper { * @return */ public static String convertKeyIdToHex(long keyId) { - return "0x" + ((keyId >> 32) > 0 ? convertKeyIdToHex32bit(keyId >> 32) : "") + convertKeyIdToHex32bit(keyId); + return "0x" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId); + } + + public static String convertKeyIdToHexShort(long keyId) { + return "0x" + convertKeyIdToHex32bit(keyId); } private static String convertKeyIdToHex32bit(long keyId) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index d8df5ced3..bd14369b0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -199,7 +199,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements // the first key here is our master key if (data.moveToFirst()) { long keyId = data.getLong(INDEX_MASTER_KEY_ID); - String keyIdStr = PgpKeyHelper.convertKeyIdToHex(keyId); + String keyIdStr = PgpKeyHelper.convertKeyIdToHexShort(keyId); ((TextView) findViewById(R.id.key_id)).setText(keyIdStr); String mainUserId = data.getString(INDEX_USER_ID); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java index 6b57fc568..960b4aafb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java @@ -71,7 +71,7 @@ public class SelectSecretKeyLayoutFragment extends Fragment { getActivity(), secretKeyId); if (keyRing != null) { PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing); - String masterkeyIdHex = PgpKeyHelper.convertKeyIdToHex(secretKeyId); + String masterkeyIdHex = PgpKeyHelper.convertKeyIdToHexShort(secretKeyId); if (key != null) { String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java index beb76fc10..fbbb9caa4 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java @@ -115,7 +115,7 @@ public class SelectKeyCursorAdapter extends HighlightQueryCursorAdapter { // TODO: needed to key id to no? keyId.setText(R.string.no_key); long masterKeyId = cursor.getLong(mIndexMasterKeyId); - keyId.setText(PgpKeyHelper.convertKeyIdToHex(masterKeyId)); + keyId.setText(PgpKeyHelper.convertKeyIdToHexShort(masterKeyId)); // TODO: needed to set unknown_status? status.setText(R.string.unknown_status); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java index 5f911275d..0064e9f13 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java @@ -86,7 +86,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter { ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey); ImageView revokedKeyIcon = (ImageView) view.findViewById(R.id.ic_revokedKey); - String keyIdStr = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId)); + String keyIdStr = PgpKeyHelper.convertKeyIdToHexShort(cursor.getLong(mIndexKeyId)); String algorithmStr = PgpKeyHelper.getAlgorithmInfo(cursor.getInt(mIndexAlgorithm), cursor.getInt(mIndexKeySize)); -- cgit v1.2.3 From 62fb1fb57931626e73e9928cc44f6eb60f3c101e Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Thu, 20 Mar 2014 00:29:40 +0100 Subject: Fix key list views in main key view Since the views are being reused, a revoked key might set the text color of a view and when the view is being reused for a non-revoked key it is still red. So grab the default text colour and set it explicitly when the key is not revoked. --- .../keychain/ui/adapter/ViewKeyKeysAdapter.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java index 0064e9f13..068d6e6e9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui.adapter; import android.content.Context; +import android.content.res.ColorStateList; import android.database.Cursor; import android.graphics.Color; import android.support.v4.widget.CursorAdapter; @@ -42,6 +43,8 @@ public class ViewKeyKeysAdapter extends CursorAdapter { private int mIndexCanSign; private int mIndexRevokedKey; + private ColorStateList mDefaultTextColor; + public ViewKeyKeysAdapter(Context context, Cursor c, int flags) { super(context, c, flags); @@ -122,13 +125,20 @@ public class ViewKeyKeysAdapter extends CursorAdapter { keyId.setTextColor(Color.RED); keyDetails.setTextColor(Color.RED); } else { + keyId.setTextColor(mDefaultTextColor); + keyDetails.setTextColor(mDefaultTextColor); revokedKeyIcon.setVisibility(View.GONE); } } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { - return mInflater.inflate(R.layout.view_key_keys_item, null); + View view = mInflater.inflate(R.layout.view_key_keys_item, null); + if (mDefaultTextColor == null) { + TextView keyId = (TextView) view.findViewById(R.id.keyId); + mDefaultTextColor = keyId.getTextColors(); + } + return view; } } -- cgit v1.2.3 From 16ae9c899949b5443c06226993ca2efc23591e72 Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Thu, 20 Mar 2014 14:09:35 +0100 Subject: Let convertKeyIdToHex handle short key IDs If a short key ID is given, then it should only be displayed as such. --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index 5b00d163a..d201a1426 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -477,6 +477,11 @@ public class PgpKeyHelper { * @return */ public static String convertKeyIdToHex(long keyId) { + long upper = keyId >> 32; + if (upper == 0) { + // this is a short key id + return convertKeyIdToHexShort(keyId); + } return "0x" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId); } -- cgit v1.2.3 From 3fa3fc444bf8a0f21d5bd2949d2141e555077f50 Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Thu, 20 Mar 2014 14:14:02 +0100 Subject: Add debug logging for hkp keyserver actions --- .../sufficientlysecure/keychain/util/HkpKeyServer.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index 9d6850027..43b40a4db 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -30,9 +30,11 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; +import org.sufficientlysecure.keychain.util.Log; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -179,6 +181,7 @@ public class HkpKeyServer extends KeyServer { for (int i = 0; i < ips.length; ++i) { try { String url = "http://" + ips[i].getHostAddress() + ":" + mPort + request; + Log.d(Constants.TAG, "hkp keyserver query: " + url); URL realUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection(); conn.setConnectTimeout(5000); @@ -277,9 +280,10 @@ public class HkpKeyServer extends KeyServer { public String get(long keyId) throws QueryException { HttpClient client = new DefaultHttpClient(); try { - HttpGet get = new HttpGet("http://" + mHost + ":" + mPort - + "/pks/lookup?op=get&options=mr&search=" + PgpKeyHelper.convertKeyIdToHex(keyId)); - + String query = "http://" + mHost + ":" + mPort + + "/pks/lookup?op=get&options=mr&search=" + PgpKeyHelper.convertKeyIdToHex(keyId); + Log.d(Constants.TAG, "hkp keyserver get: " + query); + HttpGet get = new HttpGet(query); HttpResponse response = client.execute(get); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { throw new QueryException("not found"); @@ -305,8 +309,9 @@ public class HkpKeyServer extends KeyServer { public void add(String armoredText) throws AddKeyException { HttpClient client = new DefaultHttpClient(); try { - HttpPost post = new HttpPost("http://" + mHost + ":" + mPort + "/pks/add"); - + String query = "http://" + mHost + ":" + mPort + "/pks/add"; + HttpPost post = new HttpPost(query); + Log.d(Constants.TAG, "hkp keyserver add: " + query); List nameValuePairs = new ArrayList(2); nameValuePairs.add(new BasicNameValuePair("keytext", armoredText)); post.setEntity(new UrlEncodedFormEntity(nameValuePairs)); -- cgit v1.2.3 From 2b774899322ae31f1d22999caae68c3f80985c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 20 Mar 2014 15:54:49 +0100 Subject: Dont try to parse key/fingerprint result from keyserver query --- .../keychain/pgp/PgpKeyHelper.java | 19 ++--- .../keychain/service/KeychainIntentService.java | 2 +- .../keychain/ui/adapter/ImportKeysAdapter.java | 6 +- .../keychain/ui/adapter/ImportKeysListEntry.java | 43 +++++----- .../keychain/util/HkpKeyServer.java | 98 ++++++++++++---------- .../keychain/util/KeyServer.java | 4 +- 6 files changed, 87 insertions(+), 85 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index d201a1426..09c0b2d8f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -460,12 +460,16 @@ public class PgpKeyHelper { public static String convertFingerprintToHex(byte[] fingerprint, boolean split) { String hexString = Hex.toHexString(fingerprint); if (split) { - hexString = hexString.replaceAll("(.{4})(?!$)", "$1 "); + hexString = splitFingerprintHex(hexString); } return hexString; } + public static String splitFingerprintHex(String hexString) { + return hexString.replaceAll("(.{4})(?!$)", "$1 "); + } + /** * Convert key id from long to 64 bit hex string *

@@ -497,19 +501,6 @@ public class PgpKeyHelper { return hexString; } - /** - * Used in HkpKeyServer to convert hex encoded key ids back to long. - * - * @param hexString - * @return - */ - public static long convertHexToKeyId(String hexString) { - int len = hexString.length(); - String s2 = hexString.substring(len - 8); - String s1 = hexString.substring(0, len - 8); - return ((!s1.isEmpty() ? Long.parseLong(s1, 16) << 32 : 0) | Long.parseLong(s2, 16)); - } - /** * Splits userId string into naming part, email part, and comment part * diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 6ec6dcf8a..5af81d39d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -749,7 +749,7 @@ public class KeychainIntentService extends IntentService HkpKeyServer server = new HkpKeyServer(keyServer); for (ImportKeysListEntry entry : entries) { - byte[] downloadedKey = server.get(entry.getKeyId()).getBytes(); + byte[] downloadedKey = server.get(entry.getKeyIdHex()).getBytes(); /** * TODO: copied from ImportKeysListLoader diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 0f05af447..37a8dd416 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -134,10 +134,10 @@ public class ImportKeysAdapter extends ArrayAdapter { holder.mMainUserIdRest.setVisibility(View.GONE); } - holder.mKeyId.setText(entry.hexKeyId); + holder.mKeyId.setText(entry.keyIdHex); - if (entry.fingerPrint != null) { - holder.mFingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint); + if (entry.fingerPrintHex != null) { + holder.mFingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrintHex); holder.mFingerprint.setVisibility(View.VISIBLE); } else { holder.mFingerprint.setVisibility(View.GONE); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java index 05521b0c9..d7c38213d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java @@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.ui.adapter; import android.os.Parcel; import android.os.Parcelable; import android.util.SparseArray; + import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPSecretKeyRing; @@ -38,10 +39,11 @@ public class ImportKeysListEntry implements Serializable, Parcelable { public ArrayList userIds; public long keyId; + public String keyIdHex; + public boolean revoked; public Date date; // TODO: not displayed - public String fingerPrint; - public String hexKeyId; + public String fingerPrintHex; public int bitStrength; public String algorithm; public boolean secretKey; @@ -55,8 +57,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable { this.keyId = b.keyId; this.revoked = b.revoked; this.date = b.date; - this.fingerPrint = b.fingerPrint; - this.hexKeyId = b.hexKeyId; + this.fingerPrintHex = b.fingerPrintHex; + this.keyIdHex = b.keyIdHex; this.bitStrength = b.bitStrength; this.algorithm = b.algorithm; this.secretKey = b.secretKey; @@ -74,8 +76,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable { dest.writeLong(keyId); dest.writeByte((byte) (revoked ? 1 : 0)); dest.writeSerializable(date); - dest.writeString(fingerPrint); - dest.writeString(hexKeyId); + dest.writeString(fingerPrintHex); + dest.writeString(keyIdHex); dest.writeInt(bitStrength); dest.writeString(algorithm); dest.writeByte((byte) (secretKey ? 1 : 0)); @@ -92,8 +94,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable { vr.keyId = source.readLong(); vr.revoked = source.readByte() == 1; vr.date = (Date) source.readSerializable(); - vr.fingerPrint = source.readString(); - vr.hexKeyId = source.readString(); + vr.fingerPrintHex = source.readString(); + vr.keyIdHex = source.readString(); vr.bitStrength = source.readInt(); vr.algorithm = source.readString(); vr.secretKey = source.readByte() == 1; @@ -109,8 +111,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable { } }; - public long getKeyId() { - return keyId; + public String getKeyIdHex() { + return keyIdHex; } public byte[] getBytes() { @@ -121,6 +123,14 @@ public class ImportKeysListEntry implements Serializable, Parcelable { this.mBytes = bytes; } + public boolean isSelected() { + return mSelected; + } + + public void setSelected(boolean selected) { + this.mSelected = selected; + } + /** * Constructor for later querying from keyserver */ @@ -132,14 +142,6 @@ public class ImportKeysListEntry implements Serializable, Parcelable { userIds = new ArrayList(); } - public boolean isSelected() { - return mSelected; - } - - public void setSelected(boolean selected) { - this.mSelected = selected; - } - /** * Constructor based on key object, used for import from NFC, QR Codes, files */ @@ -165,12 +167,13 @@ public class ImportKeysListEntry implements Serializable, Parcelable { for (String userId : new IterableIterator(pgpKeyRing.getPublicKey().getUserIDs())) { userIds.add(userId); } + this.keyId = pgpKeyRing.getPublicKey().getKeyID(); + this.keyIdHex = PgpKeyHelper.convertKeyIdToHex(keyId); this.revoked = pgpKeyRing.getPublicKey().isRevoked(); - this.fingerPrint = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey() + this.fingerPrintHex = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey() .getFingerprint(), true); - this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId); this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength(); final int algorithm = pgpKeyRing.getPublicKey().getAlgorithm(); this.algorithm = getAlgorithmFromId(algorithm); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index 43b40a4db..3658ef6c6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -18,7 +18,6 @@ package org.sufficientlysecure.keychain.util; -import android.text.Html; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; @@ -34,7 +33,6 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; -import org.sufficientlysecure.keychain.util.Log; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -74,26 +72,26 @@ public class HkpKeyServer extends KeyServer { /** * pub:%keyid%:%algo%:%keylen%:%creationdate%:%expirationdate%:%flags% *

    - *
  • %keyid% = this is either the fingerprint or the key ID of the key. Either the 16-digit or 8-digit - * key IDs are acceptable, but obviously the fingerprint is best.
  • - *
  • %algo% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc). - * See RFC-2440
  • - *
  • %keylen% = the key length (i.e. 1024, 2048, 4096, etc.)
  • - *
  • %creationdate% = creation date of the key in standard - * RFC-2440 form (i.e. number of seconds since - * 1/1/1970 UTC time)
  • - *
  • %expirationdate% = expiration date of the key in standard - * RFC-2440 form (i.e. number of seconds since - * 1/1/1970 UTC time)
  • - *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any order. The - * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so - * the absence of a given flag does not necessarily mean the absence of the detail. - *
      - *
    • r == revoked
    • - *
    • d == disabled
    • - *
    • e == expired
    • - *
    - *
  • + *
  • %keyid% = this is either the fingerprint or the key ID of the key. Either the 16-digit or 8-digit + * key IDs are acceptable, but obviously the fingerprint is best.
  • + *
  • %algo% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc). + * See RFC-2440
  • + *
  • %keylen% = the key length (i.e. 1024, 2048, 4096, etc.)
  • + *
  • %creationdate% = creation date of the key in standard + * RFC-2440 form (i.e. number of seconds since + * 1/1/1970 UTC time)
  • + *
  • %expirationdate% = expiration date of the key in standard + * RFC-2440 form (i.e. number of seconds since + * 1/1/1970 UTC time)
  • + *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any order. The + * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so + * the absence of a given flag does not necessarily mean the absence of the detail. + *
      + *
    • r == revoked
    • + *
    • d == disabled
    • + *
    • e == expired
    • + *
    + *
  • *
* * @see 5.2. Machine Readable Indexes @@ -107,23 +105,23 @@ public class HkpKeyServer extends KeyServer { /** * uid:%escaped uid string%:%creationdate%:%expirationdate%:%flags% *
    - *
  • %escaped uid string% = the user ID string, with HTTP %-escaping for anything that isn't 7-bit - * safe as well as for the ":" character. Any other characters may be escaped, as desired.
  • - *
  • %creationdate% = creation date of the key in standard - * RFC-2440 form (i.e. number of seconds since - * 1/1/1970 UTC time)
  • - *
  • %expirationdate% = expiration date of the key in standard - * RFC-2440 form (i.e. number of seconds since - * 1/1/1970 UTC time)
  • - *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any order. The - * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so - * the absence of a given flag does not necessarily mean the absence of the detail. - *
      - *
    • r == revoked
    • - *
    • d == disabled
    • - *
    • e == expired
    • - *
    - *
  • + *
  • %escaped uid string% = the user ID string, with HTTP %-escaping for anything that isn't 7-bit + * safe as well as for the ":" character. Any other characters may be escaped, as desired.
  • + *
  • %creationdate% = creation date of the key in standard + * RFC-2440 form (i.e. number of seconds since + * 1/1/1970 UTC time)
  • + *
  • %expirationdate% = expiration date of the key in standard + * RFC-2440 form (i.e. number of seconds since + * 1/1/1970 UTC time)
  • + *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any order. The + * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so + * the absence of a given flag does not necessarily mean the absence of the detail. + *
      + *
    • r == revoked
    • + *
    • d == disabled
    • + *
    • e == expired
    • + *
    + *
  • *
*/ public static final Pattern UID_LINE = Pattern @@ -246,8 +244,18 @@ public class HkpKeyServer extends KeyServer { final int algorithmId = Integer.decode(matcher.group(2)); info.algorithm = getAlgorithmFromId(algorithmId); - info.hexKeyId = "0x" + matcher.group(1); - info.keyId = PgpKeyHelper.convertHexToKeyId(matcher.group(1)); + // group 1 contains the full fingerprint (v4) or the long key id if available + // see https://bitbucket.org/skskeyserver/sks-keyserver/pull-request/12/fixes-for-machine-readable-indexes/diff + // and https://github.com/openpgp-keychain/openpgp-keychain/issues/259#issuecomment-38168176 + String fingerprintOrKeyId = matcher.group(1); + if (fingerprintOrKeyId.length() > 16) { + info.fingerPrintHex = "0x" + PgpKeyHelper.splitFingerprintHex(fingerprintOrKeyId); + info.keyIdHex = "0x" + fingerprintOrKeyId.substring(fingerprintOrKeyId.length() + - 16, fingerprintOrKeyId.length()); + } else { + // set key id only + info.keyIdHex = "0x" + fingerprintOrKeyId; + } final long creationDate = Long.parseLong(matcher.group(4)); final GregorianCalendar tmpGreg = new GregorianCalendar(TimeZone.getTimeZone("UTC")); @@ -277,11 +285,11 @@ public class HkpKeyServer extends KeyServer { } @Override - public String get(long keyId) throws QueryException { + public String get(String keyIdHex) throws QueryException { HttpClient client = new DefaultHttpClient(); try { String query = "http://" + mHost + ":" + mPort + - "/pks/lookup?op=get&options=mr&search=" + PgpKeyHelper.convertKeyIdToHex(keyId); + "/pks/lookup?op=get&options=mr&search=" + keyIdHex; Log.d(Constants.TAG, "hkp keyserver get: " + query); HttpGet get = new HttpGet(query); HttpResponse response = client.execute(get); @@ -306,14 +314,14 @@ public class HkpKeyServer extends KeyServer { } @Override - public void add(String armoredText) throws AddKeyException { + public void add(String armoredKey) throws AddKeyException { HttpClient client = new DefaultHttpClient(); try { String query = "http://" + mHost + ":" + mPort + "/pks/add"; HttpPost post = new HttpPost(query); Log.d(Constants.TAG, "hkp keyserver add: " + query); List nameValuePairs = new ArrayList(2); - nameValuePairs.add(new BasicNameValuePair("keytext", armoredText)); + nameValuePairs.add(new BasicNameValuePair("keytext", armoredKey)); post.setEntity(new UrlEncodedFormEntity(nameValuePairs)); HttpResponse response = client.execute(post); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java index a31fdc5ae..7f70867a5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java @@ -46,7 +46,7 @@ public abstract class KeyServer { abstract List search(String query) throws QueryException, TooManyResponses, InsufficientQuery; - abstract String get(long keyId) throws QueryException; + abstract String get(String keyIdHex) throws QueryException; - abstract void add(String armoredText) throws AddKeyException; + abstract void add(String armoredKey) throws AddKeyException; } -- cgit v1.2.3 From 36815b91851b071ded1cd5707e122f257b932555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 20 Mar 2014 16:04:05 +0100 Subject: Use getter and setter --- .../keychain/ui/adapter/ImportKeysAdapter.java | 51 ++++++++-------- .../keychain/ui/adapter/ImportKeysListEntry.java | 71 +++++++++++++++++++++- .../keychain/util/HkpKeyServer.java | 29 +++++---- 3 files changed, 111 insertions(+), 40 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 37a8dd416..d174bd0c8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -43,13 +43,12 @@ public class ImportKeysAdapter extends ArrayAdapter { protected List mData; static class ViewHolder { - private TextView mMainUserId; - private TextView mMainUserIdRest; - private TextView mKeyId; - private TextView mFingerprint; - private TextView mAlgorithm; - private TextView mStatus; - + private TextView mainUserId; + private TextView mainUserIdRest; + private TextView keyId; + private TextView fingerprint; + private TextView algorithm; + private TextView status; } public ImportKeysAdapter(Activity activity) { @@ -100,12 +99,12 @@ public class ImportKeysAdapter extends ArrayAdapter { if (convertView == null) { holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.import_keys_list_entry, null); - holder.mMainUserId = (TextView) convertView.findViewById(R.id.mainUserId); - holder.mMainUserIdRest = (TextView) convertView.findViewById(R.id.mainUserIdRest); - holder.mKeyId = (TextView) convertView.findViewById(R.id.keyId); - holder.mFingerprint = (TextView) convertView.findViewById(R.id.fingerprint); - holder.mAlgorithm = (TextView) convertView.findViewById(R.id.algorithm); - holder.mStatus = (TextView) convertView.findViewById(R.id.status); + holder.mainUserId = (TextView) convertView.findViewById(R.id.mainUserId); + holder.mainUserIdRest = (TextView) convertView.findViewById(R.id.mainUserIdRest); + holder.keyId = (TextView) convertView.findViewById(R.id.keyId); + holder.fingerprint = (TextView) convertView.findViewById(R.id.fingerprint); + holder.algorithm = (TextView) convertView.findViewById(R.id.algorithm); + holder.status = (TextView) convertView.findViewById(R.id.status); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); @@ -119,36 +118,36 @@ public class ImportKeysAdapter extends ArrayAdapter { // show red user id if it is a secret key if (entry.secretKey) { userIdSplit[0] = mActivity.getString(R.string.secret_key) + " " + userIdSplit[0]; - holder.mMainUserId.setTextColor(Color.RED); + holder.mainUserId.setTextColor(Color.RED); } - holder.mMainUserId.setText(userIdSplit[0]); + holder.mainUserId.setText(userIdSplit[0]); } else { - holder.mMainUserId.setText(R.string.user_id_no_name); + holder.mainUserId.setText(R.string.user_id_no_name); } // email if (userIdSplit[1] != null) { - holder.mMainUserIdRest.setText(userIdSplit[1]); - holder.mMainUserIdRest.setVisibility(View.VISIBLE); + holder.mainUserIdRest.setText(userIdSplit[1]); + holder.mainUserIdRest.setVisibility(View.VISIBLE); } else { - holder.mMainUserIdRest.setVisibility(View.GONE); + holder.mainUserIdRest.setVisibility(View.GONE); } - holder.mKeyId.setText(entry.keyIdHex); + holder.keyId.setText(entry.keyIdHex); if (entry.fingerPrintHex != null) { - holder.mFingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrintHex); - holder.mFingerprint.setVisibility(View.VISIBLE); + holder.fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrintHex); + holder.fingerprint.setVisibility(View.VISIBLE); } else { - holder.mFingerprint.setVisibility(View.GONE); + holder.fingerprint.setVisibility(View.GONE); } - holder.mAlgorithm.setText("" + entry.bitStrength + "/" + entry.algorithm); + holder.algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm); if (entry.revoked) { - holder.mStatus.setText(R.string.revoked); + holder.status.setText(R.string.revoked); } else { - holder.mStatus.setVisibility(View.GONE); + holder.status.setVisibility(View.GONE); } LinearLayout ll = (LinearLayout) convertView.findViewById(R.id.list); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java index d7c38213d..2610dfb3e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java @@ -36,11 +36,10 @@ import java.util.Date; public class ImportKeysListEntry implements Serializable, Parcelable { private static final long serialVersionUID = -7797972103284992662L; - public ArrayList userIds; + public ArrayList userIds; public long keyId; public String keyIdHex; - public boolean revoked; public Date date; // TODO: not displayed public String fingerPrintHex; @@ -131,6 +130,74 @@ public class ImportKeysListEntry implements Serializable, Parcelable { this.mSelected = selected; } + public long getKeyId() { + return keyId; + } + + public void setKeyId(long keyId) { + this.keyId = keyId; + } + + public void setKeyIdHex(String keyIdHex) { + this.keyIdHex = keyIdHex; + } + + public boolean isRevoked() { + return revoked; + } + + public void setRevoked(boolean revoked) { + this.revoked = revoked; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getFingerPrintHex() { + return fingerPrintHex; + } + + public void setFingerPrintHex(String fingerPrintHex) { + this.fingerPrintHex = fingerPrintHex; + } + + public int getBitStrength() { + return bitStrength; + } + + public void setBitStrength(int bitStrength) { + this.bitStrength = bitStrength; + } + + public String getAlgorithm() { + return algorithm; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public boolean isSecretKey() { + return secretKey; + } + + public void setSecretKey(boolean secretKey) { + this.secretKey = secretKey; + } + + public ArrayList getUserIds() { + return userIds; + } + + public void setUserIds(ArrayList userIds) { + this.userIds = userIds; + } + /** * Constructor for later querying from keyserver */ diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index 3658ef6c6..a25e3d748 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -239,32 +239,35 @@ public class HkpKeyServer extends KeyServer { final Matcher matcher = PUB_KEY_LINE.matcher(data); while (matcher.find()) { - final ImportKeysListEntry info = new ImportKeysListEntry(); - info.bitStrength = Integer.parseInt(matcher.group(3)); + final ImportKeysListEntry entry = new ImportKeysListEntry(); + + entry.setBitStrength(Integer.parseInt(matcher.group(3))); + final int algorithmId = Integer.decode(matcher.group(2)); - info.algorithm = getAlgorithmFromId(algorithmId); + entry.setAlgorithm(getAlgorithmFromId(algorithmId)); // group 1 contains the full fingerprint (v4) or the long key id if available // see https://bitbucket.org/skskeyserver/sks-keyserver/pull-request/12/fixes-for-machine-readable-indexes/diff // and https://github.com/openpgp-keychain/openpgp-keychain/issues/259#issuecomment-38168176 String fingerprintOrKeyId = matcher.group(1); if (fingerprintOrKeyId.length() > 16) { - info.fingerPrintHex = "0x" + PgpKeyHelper.splitFingerprintHex(fingerprintOrKeyId); - info.keyIdHex = "0x" + fingerprintOrKeyId.substring(fingerprintOrKeyId.length() - - 16, fingerprintOrKeyId.length()); + entry.setFingerPrintHex(PgpKeyHelper.splitFingerprintHex( + fingerprintOrKeyId.toLowerCase(Locale.US))); + entry.setKeyIdHex("0x" + fingerprintOrKeyId.substring(fingerprintOrKeyId.length() + - 16, fingerprintOrKeyId.length())); } else { // set key id only - info.keyIdHex = "0x" + fingerprintOrKeyId; + entry.setKeyIdHex("0x" + fingerprintOrKeyId); } final long creationDate = Long.parseLong(matcher.group(4)); final GregorianCalendar tmpGreg = new GregorianCalendar(TimeZone.getTimeZone("UTC")); tmpGreg.setTimeInMillis(creationDate * 1000); - info.date = tmpGreg.getTime(); + entry.setDate(tmpGreg.getTime()); - info.revoked = matcher.group(6).contains("r"); - info.userIds = new ArrayList(); + entry.setRevoked(matcher.group(6).contains("r")); + ArrayList userIds = new ArrayList(); final String uidLines = matcher.group(7); final Matcher uidMatcher = UID_LINE.matcher(uidLines); while (uidMatcher.find()) { @@ -277,9 +280,11 @@ public class HkpKeyServer extends KeyServer { // will never happen, because "UTF8" is supported } } - info.userIds.add(tmp); + userIds.add(tmp); } - results.add(info); + entry.setUserIds(userIds); + + results.add(entry); } return results; } -- cgit v1.2.3 From 81e0d04230963cdd6db9c64e51316533c0a1d103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 20 Mar 2014 16:09:05 +0100 Subject: colorize fingerprint in import --- .../org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index d174bd0c8..57aaf0733 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -30,7 +30,9 @@ import android.widget.CheckBox; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; + import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import java.util.ArrayList; @@ -136,7 +138,7 @@ public class ImportKeysAdapter extends ArrayAdapter { holder.keyId.setText(entry.keyIdHex); if (entry.fingerPrintHex != null) { - holder.fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrintHex); + holder.fingerprint.setText(OtherHelper.colorizeFingerprint(entry.fingerPrintHex)); holder.fingerprint.setVisibility(View.VISIBLE); } else { holder.fingerprint.setVisibility(View.GONE); -- cgit v1.2.3 From 77365202e0771abb0a1e8e3a2599ecb9664b3990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 20 Mar 2014 16:10:42 +0100 Subject: put colorize method into key helper --- .../keychain/helper/OtherHelper.java | 77 ------------------- .../keychain/pgp/PgpKeyHelper.java | 86 ++++++++++++++++++++++ .../keychain/ui/CertifyKeyActivity.java | 2 +- .../keychain/ui/ViewKeyMainFragment.java | 2 +- .../keychain/ui/adapter/ImportKeysAdapter.java | 2 +- 5 files changed, 89 insertions(+), 80 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java index 736bff02d..d0ba20ea6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java @@ -65,81 +65,4 @@ public class OtherHelper { } } - public static SpannableStringBuilder colorizeFingerprint(String fingerprint) { - SpannableStringBuilder sb = new SpannableStringBuilder(fingerprint); - try { - // for each 4 characters of the fingerprint + 1 space - for (int i = 0; i < fingerprint.length(); i += 5) { - int spanEnd = Math.min(i + 4, fingerprint.length()); - String fourChars = fingerprint.substring(i, spanEnd); - - int raw = Integer.parseInt(fourChars, 16); - byte[] bytes = {(byte) ((raw >> 8) & 0xff - 128), (byte) (raw & 0xff - 128)}; - int[] color = OtherHelper.getRgbForData(bytes); - int r = color[0]; - int g = color[1]; - int b = color[2]; - - // we cannot change black by multiplication, so adjust it to an almost-black grey, - // which will then be brightened to the minimal brightness level - if (r == 0 && g == 0 && b == 0) { - r = 1; - g = 1; - b = 1; - } - - // Convert rgb to brightness - double brightness = 0.2126 * r + 0.7152 * g + 0.0722 * b; - - // If a color is too dark to be seen on black, - // then brighten it up to a minimal brightness. - if (brightness < 80) { - double factor = 80.0 / brightness; - r = Math.min(255, (int) (r * factor)); - g = Math.min(255, (int) (g * factor)); - b = Math.min(255, (int) (b * factor)); - - // If it is too light, then darken it to a respective maximal brightness. - } else if (brightness > 180) { - double factor = 180.0 / brightness; - r = (int) (r * factor); - g = (int) (g * factor); - b = (int) (b * factor); - } - - // Create a foreground color with the 3 digest integers as RGB - // and then converting that int to hex to use as a color - sb.setSpan(new ForegroundColorSpan(Color.rgb(r, g, b)), - i, spanEnd, Spannable.SPAN_INCLUSIVE_INCLUSIVE); - } - } catch (Exception e) { - Log.e(Constants.TAG, "Colorization failed", e); - // if anything goes wrong, then just display the fingerprint without colour, - // instead of partially correct colour or wrong colours - return new SpannableStringBuilder(fingerprint); - } - - return sb; - } - - /** - * Converts the given bytes to a unique RGB color using SHA1 algorithm - * - * @param bytes - * @return an integer array containing 3 numeric color representations (Red, Green, Black) - * @throws NoSuchAlgorithmException - * @throws DigestException - */ - public static int[] getRgbForData(byte[] bytes) throws NoSuchAlgorithmException, DigestException { - MessageDigest md = MessageDigest.getInstance("SHA1"); - - md.update(bytes); - byte[] digest = md.digest(); - - int[] result = {((int) digest[0] + 256) % 256, - ((int) digest[1] + 256) % 256, - ((int) digest[2] + 256) % 256}; - return result; - } - } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index 09c0b2d8f..35412d4b8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -18,6 +18,11 @@ package org.sufficientlysecure.keychain.pgp; import android.content.Context; +import android.graphics.Color; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.style.ForegroundColorSpan; + import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.openpgp.*; import org.spongycastle.util.encoders.Hex; @@ -27,6 +32,9 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; +import java.security.DigestException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -501,6 +509,84 @@ public class PgpKeyHelper { return hexString; } + + public static SpannableStringBuilder colorizeFingerprint(String fingerprint) { + SpannableStringBuilder sb = new SpannableStringBuilder(fingerprint); + try { + // for each 4 characters of the fingerprint + 1 space + for (int i = 0; i < fingerprint.length(); i += 5) { + int spanEnd = Math.min(i + 4, fingerprint.length()); + String fourChars = fingerprint.substring(i, spanEnd); + + int raw = Integer.parseInt(fourChars, 16); + byte[] bytes = {(byte) ((raw >> 8) & 0xff - 128), (byte) (raw & 0xff - 128)}; + int[] color = getRgbForData(bytes); + int r = color[0]; + int g = color[1]; + int b = color[2]; + + // we cannot change black by multiplication, so adjust it to an almost-black grey, + // which will then be brightened to the minimal brightness level + if (r == 0 && g == 0 && b == 0) { + r = 1; + g = 1; + b = 1; + } + + // Convert rgb to brightness + double brightness = 0.2126 * r + 0.7152 * g + 0.0722 * b; + + // If a color is too dark to be seen on black, + // then brighten it up to a minimal brightness. + if (brightness < 80) { + double factor = 80.0 / brightness; + r = Math.min(255, (int) (r * factor)); + g = Math.min(255, (int) (g * factor)); + b = Math.min(255, (int) (b * factor)); + + // If it is too light, then darken it to a respective maximal brightness. + } else if (brightness > 180) { + double factor = 180.0 / brightness; + r = (int) (r * factor); + g = (int) (g * factor); + b = (int) (b * factor); + } + + // Create a foreground color with the 3 digest integers as RGB + // and then converting that int to hex to use as a color + sb.setSpan(new ForegroundColorSpan(Color.rgb(r, g, b)), + i, spanEnd, Spannable.SPAN_INCLUSIVE_INCLUSIVE); + } + } catch (Exception e) { + Log.e(Constants.TAG, "Colorization failed", e); + // if anything goes wrong, then just display the fingerprint without colour, + // instead of partially correct colour or wrong colours + return new SpannableStringBuilder(fingerprint); + } + + return sb; + } + + /** + * Converts the given bytes to a unique RGB color using SHA1 algorithm + * + * @param bytes + * @return an integer array containing 3 numeric color representations (Red, Green, Black) + * @throws java.security.NoSuchAlgorithmException + * @throws java.security.DigestException + */ + private static int[] getRgbForData(byte[] bytes) throws NoSuchAlgorithmException, DigestException { + MessageDigest md = MessageDigest.getInstance("SHA1"); + + md.update(bytes); + byte[] digest = md.digest(); + + int[] result = {((int) digest[0] + 256) % 256, + ((int) digest[1] + 256) % 256, + ((int) digest[2] + 256) % 256}; + return result; + } + /** * Splits userId string into naming part, email part, and comment part * diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index bd14369b0..0983d54fb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -211,7 +211,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri); } String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true); - ((TextView) findViewById(R.id.fingerprint)).setText(OtherHelper.colorizeFingerprint(fingerprint)); + ((TextView) findViewById(R.id.fingerprint)).setText(PgpKeyHelper.colorizeFingerprint(fingerprint)); } break; case LOADER_ID_USER_IDS: diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index e140cb21e..7beef4b5e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -322,7 +322,7 @@ public class ViewKeyMainFragment extends Fragment implements } String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true); - mFingerprint.setText(OtherHelper.colorizeFingerprint(fingerprint)); + mFingerprint.setText(PgpKeyHelper.colorizeFingerprint(fingerprint)); } mKeysAdapter.swapCursor(data); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 57aaf0733..7d3166af9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -138,7 +138,7 @@ public class ImportKeysAdapter extends ArrayAdapter { holder.keyId.setText(entry.keyIdHex); if (entry.fingerPrintHex != null) { - holder.fingerprint.setText(OtherHelper.colorizeFingerprint(entry.fingerPrintHex)); + holder.fingerprint.setText(PgpKeyHelper.colorizeFingerprint(entry.fingerPrintHex)); holder.fingerprint.setVisibility(View.VISIBLE); } else { holder.fingerprint.setVisibility(View.GONE); -- cgit v1.2.3 From a17481b80a2d717afdfc981c5c7e7528d1a7abca Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Thu, 20 Mar 2014 18:33:19 +0100 Subject: Group fingerprint again to make it visually consistent --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index 35412d4b8..ec0932773 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -511,6 +511,11 @@ public class PgpKeyHelper { public static SpannableStringBuilder colorizeFingerprint(String fingerprint) { + // add line breaks to have a consistent "image" that can be recognized + char[] chars = fingerprint.toCharArray(); + chars[24] = '\n'; + fingerprint = String.valueOf(chars); + SpannableStringBuilder sb = new SpannableStringBuilder(fingerprint); try { // for each 4 characters of the fingerprint + 1 space -- cgit v1.2.3 From 0a8b45ee88b9dcdc7a2c6e067fe65f815641b8ee Mon Sep 17 00:00:00 2001 From: Nikhil Peter Raj Date: Thu, 20 Mar 2014 23:37:29 +0530 Subject: Fix for #451 --- .../keychain/ui/SelectSecretKeyLayoutFragment.java | 164 ++++++++++++--------- 1 file changed, 96 insertions(+), 68 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java index 960b4aafb..5b441f17b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java @@ -19,22 +19,24 @@ package org.sufficientlysecure.keychain.ui; import android.app.Activity; import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; import android.os.Bundle; import android.support.v4.app.Fragment; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.provider.KeychainContract; -public class SelectSecretKeyLayoutFragment extends Fragment { +public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderManager.LoaderCallbacks { private TextView mKeyUserId; private TextView mKeyUserIdRest; @@ -43,12 +45,25 @@ public class SelectSecretKeyLayoutFragment extends Fragment { private BootstrapButton mSelectKeyButton; private Boolean mFilterCertify; + private Uri mReceivedUri = null; + private SelectSecretKeyCallback mCallback; private static final int REQUEST_CODE_SELECT_KEY = 8882; + //Loader ID needs to be different from the usual 0 + private static final int LOADER_ID = 2; + + //The Projection we will retrieve, Master Key ID is for convenience sake, + //to avoid having to pass the Key Around + final String[] PROJECTION = new String[]{KeychainContract.UserIds.USER_ID + , KeychainContract.KeyRings.MASTER_KEY_ID}; + final int INDEX_USER_ID = 0; + final int INDEX_MASTER_KEY_ID = 1; + public interface SelectSecretKeyCallback { void onKeySelected(long secretKeyId); + } public void setCallback(SelectSecretKeyCallback callback) { @@ -59,63 +74,25 @@ public class SelectSecretKeyLayoutFragment extends Fragment { mFilterCertify = filterCertify; } - public void selectKey(long secretKeyId) { - if (secretKeyId == Id.key.none) { - mNoKeySelected.setVisibility(View.VISIBLE); - mKeyUserId.setVisibility(View.GONE); - mKeyUserIdRest.setVisibility(View.GONE); - mKeyMasterKeyIdHex.setVisibility(View.GONE); + public void setNoKeySelected() { + mNoKeySelected.setVisibility(View.VISIBLE); + mKeyUserId.setVisibility(View.GONE); + mKeyUserIdRest.setVisibility(View.GONE); + mKeyMasterKeyIdHex.setVisibility(View.GONE); + } - } else { - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId( - getActivity(), secretKeyId); - if (keyRing != null) { - PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing); - String masterkeyIdHex = PgpKeyHelper.convertKeyIdToHexShort(secretKeyId); - - if (key != null) { - String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key); - - String[] userIdSplit = PgpKeyHelper.splitUserId(userId); - String userName, userEmail; - - if (userIdSplit[0] != null) { - userName = userIdSplit[0]; - } else { - userName = getActivity().getResources().getString(R.string.user_id_no_name); - } - - if (userIdSplit[1] != null) { - userEmail = userIdSplit[1]; - } else { - userEmail = getActivity().getResources().getString(R.string.error_user_id_no_email); - } - - mKeyMasterKeyIdHex.setText(masterkeyIdHex); - mKeyUserId.setText(userName); - mKeyUserIdRest.setText(userEmail); - mKeyMasterKeyIdHex.setVisibility(View.VISIBLE); - mKeyUserId.setVisibility(View.VISIBLE); - mKeyUserIdRest.setVisibility(View.VISIBLE); - mNoKeySelected.setVisibility(View.GONE); - } else { - mKeyMasterKeyIdHex.setVisibility(View.GONE); - mKeyUserId.setVisibility(View.GONE); - mKeyUserIdRest.setVisibility(View.GONE); - mNoKeySelected.setVisibility(View.VISIBLE); - } - } else { - mKeyMasterKeyIdHex.setText( - getActivity().getResources() - .getString(R.string.no_keys_added_or_updated) - + " for master id: " + secretKeyId); - mKeyMasterKeyIdHex.setVisibility(View.VISIBLE); - mKeyUserId.setVisibility(View.GONE); - mKeyUserIdRest.setVisibility(View.GONE); - mNoKeySelected.setVisibility(View.GONE); - } + public void setSelectedKeyData(String userName, String email, String masterKeyHex) { + + mNoKeySelected.setVisibility(View.GONE); + + mKeyUserId.setText(userName); + mKeyUserIdRest.setText(email); + mKeyMasterKeyIdHex.setText(masterKeyHex); + + mKeyUserId.setVisibility(View.VISIBLE); + mKeyUserIdRest.setVisibility(View.VISIBLE); + mKeyMasterKeyIdHex.setVisibility(View.VISIBLE); - } } public void setError(String error) { @@ -147,29 +124,80 @@ public class SelectSecretKeyLayoutFragment extends Fragment { return view; } + //For AppSettingsFragment + public void selectKey(long masterKeyId){ + Uri buildUri = KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(masterKeyId)); + mReceivedUri=buildUri; + getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this); + } + private void startSelectKeyActivity() { Intent intent = new Intent(getActivity(), SelectSecretKeyActivity.class); intent.putExtra(SelectSecretKeyActivity.EXTRA_FILTER_CERTIFY, mFilterCertify); startActivityForResult(intent, REQUEST_CODE_SELECT_KEY); } + @Override + public Loader onCreateLoader(int id, Bundle args) { + //We don't care about the Loader id + return new CursorLoader(getActivity(), mReceivedUri, PROJECTION, null, null, null); + } + + @Override + public void onLoadFinished(Loader loader, Cursor data) { + if (data.moveToFirst()) { + String userName, email, masterKeyHex; + String userID = data.getString(INDEX_USER_ID); + long masterKeyID = data.getLong(INDEX_MASTER_KEY_ID); + + String splitUserID[] = PgpKeyHelper.splitUserId(userID); + + if (splitUserID[0] != null) { + userName = splitUserID[0]; + } else { + userName = getActivity().getResources().getString(R.string.user_id_no_name); + } + + if (splitUserID[1] != null) { + email = splitUserID[1]; + } else { + email = getActivity().getResources().getString(R.string.error_user_id_no_email); + } + + //TODO Can the cursor return invalid values for the Master Key ? + masterKeyHex = PgpKeyHelper.convertKeyIdToHexShort(masterKeyID); + + //Set the data + setSelectedKeyData(userName, email, masterKeyHex); + + //Give value to the callback + mCallback.onKeySelected(masterKeyID); + } else { + //Set The empty View + setNoKeySelected(); + } + + } + + @Override + public void onLoaderReset(Loader loader) { + return; + } + // Select Secret Key Activity delivers the intent which was sent by it using interface to Select - // Secret Key Fragment.Intent contains Master Key Id, User Email, User Name, Master Key Id Hex. + // Secret Key Fragment.Intent contains the passed Uri @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode & 0xFFFF) { case REQUEST_CODE_SELECT_KEY: { - long secretKeyId; if (resultCode == Activity.RESULT_OK) { - Bundle bundle = data.getExtras(); - secretKeyId = bundle.getLong(SelectSecretKeyActivity.RESULT_EXTRA_MASTER_KEY_ID); - selectKey(secretKeyId); + mReceivedUri = data.getData(); + + //Must be restartLoader() or the data will not be updated on selecting a new key + getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this); - // remove displayed errors mKeyUserId.setError(null); - // give value back to callback - mCallback.onKeySelected(secretKeyId); } break; } -- cgit v1.2.3 From 0510e0e217f5b7bab548dccf7bdd75f2bd5c0463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 20 Mar 2014 19:11:51 +0100 Subject: verify downloaded key by comparing fingerprints --- .../keychain/service/KeychainIntentService.java | 80 ++++++++++++---------- 1 file changed, 45 insertions(+), 35 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 5af81d39d..19358adc9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -25,6 +25,7 @@ import android.os.Bundle; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; + import org.spongycastle.openpgp.*; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; @@ -692,11 +693,11 @@ public class KeychainIntentService extends IntentService for (long masterKeyId : masterKeyIds) { if ((keyType == Id.type.public_key || keyType == Id.type.public_secret_key) - && allPublicMasterKeyIds.contains(masterKeyId)) { + && allPublicMasterKeyIds.contains(masterKeyId)) { publicMasterKeyIds.add(masterKeyId); } if ((keyType == Id.type.secret_key || keyType == Id.type.public_secret_key) - && allSecretMasterKeyIds.contains(masterKeyId)) { + && allSecretMasterKeyIds.contains(masterKeyId)) { secretMasterKeyIds.add(masterKeyId); } } @@ -745,49 +746,58 @@ public class KeychainIntentService extends IntentService ArrayList entries = data.getParcelableArrayList(DOWNLOAD_KEY_LIST); String keyServer = data.getString(DOWNLOAD_KEY_SERVER); + // TODO: add extra which requires fingerprint suport and force verification! + // only supported by newer sks keyserver versions + // this downloads the keys and places them into the ImportKeysListEntry entries HkpKeyServer server = new HkpKeyServer(keyServer); for (ImportKeysListEntry entry : entries) { - byte[] downloadedKey = server.get(entry.getKeyIdHex()).getBytes(); - - /** - * TODO: copied from ImportKeysListLoader - * - * - * this parses the downloaded key - */ - // need to have access to the bufferedInput, so we can reuse it for the possible - // PGPObject chunks after the first one, e.g. files with several consecutive ASCII - // armor blocks - BufferedInputStream bufferedInput = - new BufferedInputStream(new ByteArrayInputStream(downloadedKey)); - try { - - // read all available blocks... (asc files can contain many blocks with BEGIN END) - while (bufferedInput.available() > 0) { - InputStream in = PGPUtil.getDecoderStream(bufferedInput); - PGPObjectFactory objectFactory = new PGPObjectFactory(in); - - // go through all objects in this block - Object obj; - while ((obj = objectFactory.nextObject()) != null) { - Log.d(Constants.TAG, "Found class: " + obj.getClass()); - - if (obj instanceof PGPKeyRing) { - PGPKeyRing newKeyring = (PGPKeyRing) obj; + // if available use complete fingerprint for get request + byte[] downloadedKeyBytes; + if (entry.getFingerPrintHex() != null) { + downloadedKeyBytes = server.get(entry.getFingerPrintHex()).getBytes(); + } else { + downloadedKeyBytes = server.get(entry.getKeyIdHex()).getBytes(); + } - entry.setBytes(newKeyring.getEncoded()); - } else { - Log.e(Constants.TAG, "Object not recognized as PGPKeyRing!"); - } + // create PGPKeyRing object based on downloaded armored key + PGPKeyRing downloadedKey = null; + BufferedInputStream bufferedInput = + new BufferedInputStream(new ByteArrayInputStream(downloadedKeyBytes)); + if (bufferedInput.available() > 0) { + InputStream in = PGPUtil.getDecoderStream(bufferedInput); + PGPObjectFactory objectFactory = new PGPObjectFactory(in); + + // get first object in block + Object obj; + if ((obj = objectFactory.nextObject()) != null) { + Log.d(Constants.TAG, "Found class: " + obj.getClass()); + + if (obj instanceof PGPKeyRing) { + downloadedKey = (PGPKeyRing) obj; + } else { + throw new PgpGeneralException("Object not recognized as PGPKeyRing!"); } } - } catch (Exception e) { - Log.e(Constants.TAG, "Exception on parsing key file!", e); } + + // verify downloaded key by comparing fingerprints + if (entry.getFingerPrintHex() != null) { + String downloadedKeyFp = PgpKeyHelper.convertFingerprintToHex(downloadedKey.getPublicKey().getFingerprint(), false); + if (downloadedKeyFp.equals(entry.getFingerPrintHex())) { + Log.d(Constants.TAG, "fingerprint of downloaded key is the same as the requested fingerprint!"); + } else { + throw new PgpGeneralException("fingerprint of downloaded key is NOT the same as the requested fingerprint!"); + } + } + + // save key bytes in entry object for doing the + // actual import afterwards + entry.setBytes(downloadedKey.getEncoded()); } + Intent importIntent = new Intent(this, KeychainIntentService.class); importIntent.setAction(ACTION_IMPORT_KEYRING); Bundle importData = new Bundle(); -- cgit v1.2.3 From 016641a422ddff652b697a76d7ed59ab9954239e Mon Sep 17 00:00:00 2001 From: Nikhil Peter Raj Date: Thu, 20 Mar 2014 23:46:26 +0530 Subject: Cleanup for #451 --- .../org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java | 4 ---- .../sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java | 1 - 2 files changed, 5 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java index 82a3c2e8e..0ff88d97c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java @@ -76,10 +76,6 @@ public class SelectSecretKeyActivity extends ActionBarActivity { Intent data = new Intent(); data.setData(selectedUri); - // TODO: deprecate RESULT_EXTRA_MASTER_KEY_ID! - long masterKeyId = Long.valueOf(selectedUri.getLastPathSegment()); - data.putExtra(RESULT_EXTRA_MASTER_KEY_ID, masterKeyId); - setResult(RESULT_OK, data); finish(); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java index 5b441f17b..41e250bb7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java @@ -63,7 +63,6 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan public interface SelectSecretKeyCallback { void onKeySelected(long secretKeyId); - } public void setCallback(SelectSecretKeyCallback callback) { -- cgit v1.2.3 From 59d51fe68eb6502c313c6a74d4a1e04d0e959b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 20 Mar 2014 19:48:18 +0100 Subject: Fix fingerprint handling --- .../org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java | 14 +++++--------- .../keychain/service/KeychainIntentService.java | 4 ++-- .../sufficientlysecure/keychain/ui/CertifyKeyActivity.java | 4 +++- .../sufficientlysecure/keychain/ui/ViewKeyActivity.java | 2 +- .../keychain/ui/ViewKeyMainFragment.java | 2 +- .../keychain/ui/adapter/ImportKeysListEntry.java | 2 +- .../keychain/ui/dialog/ShareQrCodeDialogFragment.java | 2 +- .../org/sufficientlysecure/keychain/util/HkpKeyServer.java | 3 +-- 8 files changed, 15 insertions(+), 18 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index ec0932773..b7db92b9b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -452,7 +452,7 @@ public class PgpKeyHelper { key = secretKey.getPublicKey(); } - return convertFingerprintToHex(key.getFingerprint(), true); + return convertFingerprintToHex(key.getFingerprint()); } /** @@ -465,19 +465,12 @@ public class PgpKeyHelper { * @param split split into 4 character chunks * @return */ - public static String convertFingerprintToHex(byte[] fingerprint, boolean split) { + public static String convertFingerprintToHex(byte[] fingerprint) { String hexString = Hex.toHexString(fingerprint); - if (split) { - hexString = splitFingerprintHex(hexString); - } return hexString; } - public static String splitFingerprintHex(String hexString) { - return hexString.replaceAll("(.{4})(?!$)", "$1 "); - } - /** * Convert key id from long to 64 bit hex string *

@@ -511,6 +504,9 @@ public class PgpKeyHelper { public static SpannableStringBuilder colorizeFingerprint(String fingerprint) { + // split by 4 characters + fingerprint = fingerprint.replaceAll("(.{4})(?!$)", "$1 "); + // add line breaks to have a consistent "image" that can be recognized char[] chars = fingerprint.toCharArray(); chars[24] = '\n'; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 19358adc9..0751fa33c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -756,7 +756,7 @@ public class KeychainIntentService extends IntentService // if available use complete fingerprint for get request byte[] downloadedKeyBytes; if (entry.getFingerPrintHex() != null) { - downloadedKeyBytes = server.get(entry.getFingerPrintHex()).getBytes(); + downloadedKeyBytes = server.get("0x" + entry.getFingerPrintHex()).getBytes(); } else { downloadedKeyBytes = server.get(entry.getKeyIdHex()).getBytes(); } @@ -784,7 +784,7 @@ public class KeychainIntentService extends IntentService // verify downloaded key by comparing fingerprints if (entry.getFingerPrintHex() != null) { - String downloadedKeyFp = PgpKeyHelper.convertFingerprintToHex(downloadedKey.getPublicKey().getFingerprint(), false); + String downloadedKeyFp = PgpKeyHelper.convertFingerprintToHex(downloadedKey.getPublicKey().getFingerprint()); if (downloadedKeyFp.equals(entry.getFingerPrintHex())) { Log.d(Constants.TAG, "fingerprint of downloaded key is the same as the requested fingerprint!"); } else { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index 0983d54fb..dff4e9d72 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -198,6 +198,8 @@ public class CertifyKeyActivity extends ActionBarActivity implements case LOADER_ID_KEYRING: // the first key here is our master key if (data.moveToFirst()) { + // TODO: put findViewById in onCreate! + long keyId = data.getLong(INDEX_MASTER_KEY_ID); String keyIdStr = PgpKeyHelper.convertKeyIdToHexShort(keyId); ((TextView) findViewById(R.id.key_id)).setText(keyIdStr); @@ -210,7 +212,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements // FALLBACK for old database entries fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri); } - String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true); + String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); ((TextView) findViewById(R.id.fingerprint)).setText(PgpKeyHelper.colorizeFingerprint(fingerprint)); } break; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index c4097403c..41bd95db3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -182,7 +182,7 @@ public class ViewKeyActivity extends ActionBarActivity { String content; if (fingerprintOnly) { byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri); - String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, false); + String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint; } else { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index 7beef4b5e..dd4e7fa94 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -320,7 +320,7 @@ public class ViewKeyMainFragment extends Fragment implements // FALLBACK for old database entries fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), mDataUri); } - String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true); + String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); mFingerprint.setText(PgpKeyHelper.colorizeFingerprint(fingerprint)); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java index 2610dfb3e..9b20effc2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java @@ -240,7 +240,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable { this.revoked = pgpKeyRing.getPublicKey().isRevoked(); this.fingerPrintHex = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey() - .getFingerprint(), true); + .getFingerprint()); this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength(); final int algorithm = pgpKeyRing.getPublicKey().getAlgorithm(); this.algorithm = getAlgorithmFromId(algorithm); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java index b501ba230..94586810e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java @@ -90,7 +90,7 @@ public class ShareQrCodeDialogFragment extends DialogFragment { alert.setPositiveButton(R.string.btn_okay, null); byte[] fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), dataUri); - String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, false); + String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); mText.setText(getString(R.string.share_qr_code_dialog_fingerprint_text) + " " + fingerprint); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index a25e3d748..b987e1533 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -251,8 +251,7 @@ public class HkpKeyServer extends KeyServer { // and https://github.com/openpgp-keychain/openpgp-keychain/issues/259#issuecomment-38168176 String fingerprintOrKeyId = matcher.group(1); if (fingerprintOrKeyId.length() > 16) { - entry.setFingerPrintHex(PgpKeyHelper.splitFingerprintHex( - fingerprintOrKeyId.toLowerCase(Locale.US))); + entry.setFingerPrintHex(fingerprintOrKeyId.toLowerCase(Locale.US)); entry.setKeyIdHex("0x" + fingerprintOrKeyId.substring(fingerprintOrKeyId.length() - 16, fingerprintOrKeyId.length())); } else { -- cgit v1.2.3 From d9b909a24f4b32225027451062ed6304b1cf9a2e Mon Sep 17 00:00:00 2001 From: Nikhil Peter Raj Date: Fri, 21 Mar 2014 00:27:03 +0530 Subject: Update fix for #451 --- .../keychain/ui/SelectSecretKeyLayoutFragment.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java index 41e250bb7..2fcfc9650 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java @@ -50,9 +50,8 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan private SelectSecretKeyCallback mCallback; private static final int REQUEST_CODE_SELECT_KEY = 8882; - - //Loader ID needs to be different from the usual 0 - private static final int LOADER_ID = 2; + + private static final int LOADER_ID = 0; //The Projection we will retrieve, Master Key ID is for convenience sake, //to avoid having to pass the Key Around -- cgit v1.2.3 From 2816461283c0067f524d94ddf9702e119025c9d3 Mon Sep 17 00:00:00 2001 From: Nikhil Peter Raj Date: Fri, 21 Mar 2014 01:50:20 +0530 Subject: Fix for #410 --- .../keychain/helper/ExportHelper.java | 4 +- .../keychain/provider/ProviderHelper.java | 23 ++- .../keychain/ui/EditKeyActivity.java | 14 +- .../keychain/ui/KeyListFragment.java | 22 +-- .../keychain/ui/ViewKeyActivity.java | 19 +- .../ui/dialog/DeleteKeyDialogFragment.java | 207 ++++++++++++--------- 6 files changed, 147 insertions(+), 142 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java index 03cf936ee..2bfa796c7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java @@ -53,14 +53,14 @@ public class ExportHelper { this.mActivity = activity; } - public void deleteKey(Uri dataUri, final int keyType, Handler deleteHandler) { + public void deleteKey(Uri dataUri, Handler deleteHandler) { long keyRingRowId = Long.valueOf(dataUri.getLastPathSegment()); // Create a new Messenger for the communication back Messenger messenger = new Messenger(deleteHandler); DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger, - new long[]{keyRingRowId}, keyType); + new long[]{keyRingRowId}); deleteKeyDialog.show(mActivity.getSupportFragmentManager(), "deleteKeyDialog"); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index db2c57207..8b6feeafd 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Dominik Schürmann + * Copyright (C) 2012-2013 Dominik Schürmann * * 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 @@ -230,7 +230,7 @@ public class ProviderHelper { // get current _ID of key long currentRowId = -1; Cursor oldQuery = context.getContentResolver() - .query(deleteUri, new String[]{KeyRings._ID}, null, null, null); + .query(deleteUri, new String[]{KeyRings._ID}, null, null, null); if (oldQuery != null && oldQuery.moveToFirst()) { currentRowId = oldQuery.getLong(0); } else { @@ -288,7 +288,7 @@ public class ProviderHelper { * Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing */ private static ContentProviderOperation buildPublicKeyOperations(Context context, - long keyRingRowId, PGPPublicKey key, int rank) throws IOException { + long keyRingRowId, PGPPublicKey key, int rank) throws IOException { ContentValues values = new ContentValues(); values.put(Keys.KEY_ID, key.getKeyID()); values.put(Keys.IS_MASTER_KEY, key.isMasterKey()); @@ -316,7 +316,7 @@ public class ProviderHelper { * Build ContentProviderOperation to add PublicUserIds to database corresponding to a keyRing */ private static ContentProviderOperation buildPublicUserIdOperations(Context context, - long keyRingRowId, String userId, int rank) { + long keyRingRowId, String userId, int rank) { ContentValues values = new ContentValues(); values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId); values.put(UserIds.USER_ID, userId); @@ -331,7 +331,7 @@ public class ProviderHelper { * Build ContentProviderOperation to add PGPSecretKey to database corresponding to a keyRing */ private static ContentProviderOperation buildSecretKeyOperations(Context context, - long keyRingRowId, PGPSecretKey key, int rank) throws IOException { + long keyRingRowId, PGPSecretKey key, int rank) throws IOException { ContentValues values = new ContentValues(); boolean hasPrivate = true; @@ -368,7 +368,7 @@ public class ProviderHelper { * Build ContentProviderOperation to add SecretUserIds to database corresponding to a keyRing */ private static ContentProviderOperation buildSecretUserIdOperations(Context context, - long keyRingRowId, String userId, int rank) { + long keyRingRowId, String userId, int rank) { ContentValues values = new ContentValues(); values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId); values.put(UserIds.USER_ID, userId); @@ -469,6 +469,15 @@ public class ProviderHelper { cr.delete(KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)), null, null); } + public static void deleteUnifiedKeyRing(Context context,String masterKeyId,boolean isSecretKey){ + ContentResolver cr= context.getContentResolver(); + cr.delete(KeyRings.buildPublicKeyRingsByMasterKeyIdUri(masterKeyId),null,null); + if(isSecretKey){ + cr.delete(KeyRings.buildSecretKeyRingsByMasterKeyIdUri(masterKeyId),null,null); + } + + } + /** * Get master key id of keyring by its row id */ @@ -855,4 +864,4 @@ public class ProviderHelper { return signature; } -} +} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 31804719f..654942db7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Dominik Schürmann + * Copyright (C) 2012-2013 Dominik Schürmann * Copyright (C) 2010 Thialfihar * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -46,6 +46,7 @@ import org.sufficientlysecure.keychain.helper.ExportHelper; import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; @@ -58,7 +59,6 @@ import org.sufficientlysecure.keychain.ui.widget.SectionView; import org.sufficientlysecure.keychain.ui.widget.UserIdEditor; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; - import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.Vector; @@ -325,9 +325,13 @@ public class EditKeyActivity extends ActionBarActivity { long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri); long[] ids = new long[]{masterKeyId}; mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC, - null); + null); return true; case R.id.menu_key_edit_delete: { + //Convert the uri to one based on rowId + long rowId= ProviderHelper.getRowId(this,mDataUri); + Uri convertUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)); + // Message is received after key is deleted Handler returnHandler = new Handler() { @Override @@ -339,7 +343,7 @@ public class EditKeyActivity extends ActionBarActivity { } }; - mExportHelper.deleteKey(mDataUri, Id.type.secret_key, returnHandler); + mExportHelper.deleteKey(convertUri, returnHandler); return true; } } @@ -697,4 +701,4 @@ public class EditKeyActivity extends ActionBarActivity { : getString(R.string.btn_set_passphrase)); } -} +} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index cac8b7046..daf455c03 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -355,25 +355,7 @@ public class KeyListFragment extends Fragment @Override public void handleMessage(Message message) { if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) { - Bundle returnData = message.getData(); - if (returnData != null - && returnData.containsKey(DeleteKeyDialogFragment.MESSAGE_NOT_DELETED)) { - ArrayList notDeleted = - returnData.getStringArrayList(DeleteKeyDialogFragment.MESSAGE_NOT_DELETED); - String notDeletedMsg = ""; - for (String userId : notDeleted) { - notDeletedMsg += userId + "\n"; - } - Toast.makeText(getActivity(), - getString(R.string.error_can_not_delete_contacts, notDeletedMsg) - + getResources() - .getQuantityString( - R.plurals.error_can_not_delete_info, - notDeleted.size()), - Toast.LENGTH_LONG).show(); - - mode.finish(); - } + mode.finish(); } } }; @@ -382,7 +364,7 @@ public class KeyListFragment extends Fragment Messenger messenger = new Messenger(returnHandler); DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger, - keyRingRowIds, Id.type.public_key); + keyRingRowIds); deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog"); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index c4097403c..5e7cabcac 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -237,25 +237,12 @@ public class ViewKeyActivity extends ActionBarActivity { Handler returnHandler = new Handler() { @Override public void handleMessage(Message message) { - if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) { - Bundle returnData = message.getData(); - if (returnData != null - && returnData.containsKey(DeleteKeyDialogFragment.MESSAGE_NOT_DELETED)) { - // we delete only this key, so MESSAGE_NOT_DELETED will solely contain this key - Toast.makeText(ViewKeyActivity.this, - getString(R.string.error_can_not_delete_contact) - + getResources() - .getQuantityString(R.plurals.error_can_not_delete_info, 1), - Toast.LENGTH_LONG).show(); - } else { - setResult(RESULT_CANCELED); - finish(); - } - } + setResult(RESULT_CANCELED); + finish(); } }; - mExportHelper.deleteKey(dataUri, Id.type.public_key, returnHandler); + mExportHelper.deleteKey(dataUri, returnHandler); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index 1bcf5b33c..76a69328a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Dominik Schürmann + * Copyright (C) 2013-2014 Dominik Schürmann * * 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 @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package org.sufficientlysecure.keychain.ui.dialog; import android.app.AlertDialog; @@ -28,6 +27,11 @@ import android.os.Messenger; import android.os.RemoteException; import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentActivity; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.CheckBox; +import android.widget.LinearLayout; +import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; @@ -35,148 +39,167 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.Log; - import java.util.ArrayList; public class DeleteKeyDialogFragment extends DialogFragment { private static final String ARG_MESSENGER = "messenger"; private static final String ARG_DELETE_KEY_RING_ROW_IDS = "delete_file"; - private static final String ARG_KEY_TYPE = "key_type"; public static final int MESSAGE_OKAY = 1; + public static final int MESSAGE_ERROR = 0; + + private boolean isSingleSelection = false; - public static final String MESSAGE_NOT_DELETED = "not_deleted"; + private TextView mainMessage; + private CheckBox checkDeleteSecret; + private LinearLayout deleteSecretKeyView; + private View inflateView; private Messenger mMessenger; /** * Creates new instance of this delete file dialog fragment */ - public static DeleteKeyDialogFragment newInstance(Messenger messenger, long[] keyRingRowIds, - int keyType) { + public static DeleteKeyDialogFragment newInstance(Messenger messenger, long[] keyRingRowIds + ) { DeleteKeyDialogFragment frag = new DeleteKeyDialogFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_MESSENGER, messenger); args.putLongArray(ARG_DELETE_KEY_RING_ROW_IDS, keyRingRowIds); - args.putInt(ARG_KEY_TYPE, keyType); + //We don't need the key type frag.setArguments(args); return frag; } - /** - * Creates dialog - */ + @Override public Dialog onCreateDialog(Bundle savedInstanceState) { + final FragmentActivity activity = getActivity(); mMessenger = getArguments().getParcelable(ARG_MESSENGER); final long[] keyRingRowIds = getArguments().getLongArray(ARG_DELETE_KEY_RING_ROW_IDS); - final int keyType = getArguments().getInt(ARG_KEY_TYPE); AlertDialog.Builder builder = new AlertDialog.Builder(activity); + + //Setup custom View to display in AlertDialog + LayoutInflater inflater = activity.getLayoutInflater(); + inflateView = inflater.inflate(R.layout.view_key_delete_fragment, null); + builder.setView(inflateView); + + deleteSecretKeyView = (LinearLayout) inflateView.findViewById(R.id.deleteSecretKeyView); + mainMessage = (TextView) inflateView.findViewById(R.id.mainMessage); + checkDeleteSecret = (CheckBox) inflateView.findViewById(R.id.checkDeleteSecret); + builder.setTitle(R.string.warning); + //If only a single key has been selected if (keyRingRowIds.length == 1) { Uri dataUri; - if (keyType == Id.type.public_key) { - dataUri = KeychainContract.KeyRings.buildPublicKeyRingsUri(String.valueOf(keyRingRowIds[0])); + ArrayList publicKeyRings; //Any one will do + isSingleSelection = true; + + long selectedRow = keyRingRowIds[0]; + long keyType; + publicKeyRings = ProviderHelper.getPublicKeyRingsRowIds(activity); + + if (publicKeyRings.contains(selectedRow)) { + //TODO Should be a better method to do this other than getting all the KeyRings + dataUri = KeychainContract.KeyRings.buildPublicKeyRingsUri(String.valueOf(selectedRow)); + keyType = Id.type.public_key; } else { - dataUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowIds[0])); + dataUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(String.valueOf(selectedRow)); + keyType = Id.type.secret_key; } + String userId = ProviderHelper.getUserId(activity, dataUri); + //Hide the Checkbox and TextView since this is a single selection,user will be notified thru message + deleteSecretKeyView.setVisibility(View.GONE); + //Set message depending on which key it is. + mainMessage.setText(getString(keyType == Id.type.secret_key ? R.string.secret_key_deletion_confirmation + : R.string.public_key_deletetion_confirmation, userId)); + - builder.setMessage(getString( - keyType == Id.type.public_key ? R.string.key_deletion_confirmation - : R.string.secret_key_deletion_confirmation, userId)); } else { - builder.setMessage(R.string.key_deletion_confirmation_multi); + deleteSecretKeyView.setVisibility(View.VISIBLE); + mainMessage.setText(R.string.key_deletion_confirmation_multi); } + builder.setIcon(R.drawable.ic_dialog_alert_holo_light); builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int id) { - ArrayList notDeleted = new ArrayList(); - - if (keyType == Id.type.public_key) { - Uri queryUri = KeychainContract.KeyRings.buildPublicKeyRingsUri(); - String[] projection = new String[]{ - KeychainContract.KeyRings._ID, // 0 - KeychainContract.KeyRings.MASTER_KEY_ID, // 1 - KeychainContract.UserIds.USER_ID // 2 - }; - - // make selection with all entries where _ID is one of the given row ids - String selection = KeychainDatabase.Tables.KEY_RINGS + "." + - KeychainContract.KeyRings._ID + " IN("; - String selectionIDs = ""; - for (int i = 0; i < keyRingRowIds.length; i++) { - selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'"; - if (i + 1 < keyRingRowIds.length) { - selectionIDs += ","; + @Override + public void onClick(DialogInterface dialog, int which) { + Uri queryUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri(); + String[] projection = new String[]{ + KeychainContract.KeyRings.MASTER_KEY_ID, // 0 + KeychainContract.KeyRings.TYPE// 1 + }; + + // make selection with all entries where _ID is one of the given row ids + String selection = KeychainDatabase.Tables.KEY_RINGS + "." + + KeychainContract.KeyRings._ID + " IN("; + String selectionIDs = ""; + for (int i = 0; i < keyRingRowIds.length; i++) { + selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'"; + if (i + 1 < keyRingRowIds.length) + selectionIDs += ","; } - } - selection += selectionIDs + ")"; - - Cursor cursor = activity.getContentResolver().query(queryUri, projection, - selection, null, null); - - long rowId; - long masterKeyId; - String userId; - try { - while (cursor != null && cursor.moveToNext()) { - rowId = cursor.getLong(0); - masterKeyId = cursor.getLong(1); - userId = cursor.getString(2); - - Log.d(Constants.TAG, "rowId: " + rowId + ", masterKeyId: " + masterKeyId - + ", userId: " + userId); - - // check if a corresponding secret key exists... - Cursor secretCursor = activity.getContentResolver().query( - KeychainContract.KeyRings - .buildSecretKeyRingsByMasterKeyIdUri( - String.valueOf(masterKeyId)), - null, null, null, null - ); - if (secretCursor != null && secretCursor.getCount() > 0) { - notDeleted.add(userId); - } else { - // it is okay to delete this key, no secret key found! - ProviderHelper.deletePublicKeyRing(activity, rowId); + selection += selectionIDs + ")"; + + Cursor cursor = activity.getContentResolver().query(queryUri, projection, + selection, null, null); + + + long masterKeyId; + long keyType; + boolean isSuccessfullyDeleted; + try { + isSuccessfullyDeleted = false; + while (cursor != null && cursor.moveToNext()) { + masterKeyId = cursor.getLong(0); + keyType = cursor.getLong(1); + + Log.d(Constants.TAG, "masterKeyId: " + masterKeyId + + ", keyType:" + (keyType == KeychainContract.KeyTypes.PUBLIC ? "Public" : "Private")); + + + if (keyType == KeychainContract.KeyTypes.SECRET) { + if (checkDeleteSecret.isChecked() || isSingleSelection) { + ProviderHelper.deleteUnifiedKeyRing(activity, String.valueOf(masterKeyId), true); + } + } else { + ProviderHelper.deleteUnifiedKeyRing(activity, String.valueOf(masterKeyId), false); + } } - if (secretCursor != null) { - secretCursor.close(); + + //Check if the selected rows have actually been deleted + cursor = activity.getContentResolver().query(queryUri, projection, selection, null, null); + if (cursor == null || cursor.getCount() == 0 || !checkDeleteSecret.isChecked()) { + isSuccessfullyDeleted = true; + } + + } finally { + if (cursor != null) { + cursor.close(); } + } - } finally { - if (cursor != null) { - cursor.close(); + + dismiss(); + + if (isSuccessfullyDeleted) { + sendMessageToHandler(MESSAGE_OKAY, null); + } else { + sendMessageToHandler(MESSAGE_ERROR, null); } } - } else { - for (long keyRowId : keyRingRowIds) { - ProviderHelper.deleteSecretKeyRing(activity, keyRowId); - } - } - - dismiss(); - if (notDeleted.size() > 0) { - Bundle data = new Bundle(); - data.putStringArrayList(MESSAGE_NOT_DELETED, notDeleted); - sendMessageToHandler(MESSAGE_OKAY, data); - } else { - sendMessageToHandler(MESSAGE_OKAY, null); } - } - }); + ); builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override @@ -198,7 +221,6 @@ public class DeleteKeyDialogFragment extends DialogFragment { if (data != null) { msg.setData(data); } - try { mMessenger.send(msg); } catch (RemoteException e) { @@ -207,4 +229,5 @@ public class DeleteKeyDialogFragment extends DialogFragment { Log.w(Constants.TAG, "Messenger is null!", e); } } -} + +} \ No newline at end of file -- cgit v1.2.3 From 4e6325a14068c173ed4372f60a3fae968b676e51 Mon Sep 17 00:00:00 2001 From: Nikhil Peter Raj Date: Fri, 21 Mar 2014 01:56:33 +0530 Subject: Fix GPL Headers --- .../java/org/sufficientlysecure/keychain/provider/ProviderHelper.java | 2 +- .../main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 2 +- .../sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 8b6feeafd..2fa903fe2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Dominik Schürmann + * Copyright (C) 2012-2013 Dominik Schürmann * * 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 diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 654942db7..9b64def1e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Dominik Schürmann + * Copyright (C) 2012-2013 Dominik Schürmann * Copyright (C) 2010 Thialfihar * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index 76a69328a..a43debd07 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 Dominik Schürmann + * Copyright (C) 2013-2014 Dominik Schürmann * * 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 -- cgit v1.2.3 From 2f0075e043daab6d59e38cdb110960895a06a2b4 Mon Sep 17 00:00:00 2001 From: Daniel Hammann Date: Thu, 20 Mar 2014 22:35:05 +0100 Subject: URI is transported in intents data not extra. --- .../main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 1231b6209..28c9c7b28 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -1002,8 +1002,8 @@ public class EncryptActivity extends DrawerActivity { case Id.request.secret_keys: { if (resultCode == RESULT_OK) { - Bundle bundle = data.getExtras(); - mSecretKeyId = bundle.getLong(SelectSecretKeyActivity.RESULT_EXTRA_MASTER_KEY_ID); + Uri uri_master_key = data.getData(); + mSecretKeyId = Long.valueOf(uri_master_key.getLastPathSegment()); } else { mSecretKeyId = Id.key.none; } -- cgit v1.2.3 From 620c67f4412fa56d7edfbfad3ace13f3e409ac5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 21 Mar 2014 10:05:59 +0100 Subject: reformat merge --- .../keychain/ui/SelectSecretKeyLayoutFragment.java | 8 +- .../ui/dialog/DeleteKeyDialogFragment.java | 115 +++++++++++---------- 2 files changed, 64 insertions(+), 59 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java index 2fcfc9650..cbc0f4c5c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java @@ -31,7 +31,9 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.TextView; + import com.beardedhen.androidbootstrap.BootstrapButton; + import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract; @@ -50,7 +52,7 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan private SelectSecretKeyCallback mCallback; private static final int REQUEST_CODE_SELECT_KEY = 8882; - + private static final int LOADER_ID = 0; //The Projection we will retrieve, Master Key ID is for convenience sake, @@ -123,9 +125,9 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan } //For AppSettingsFragment - public void selectKey(long masterKeyId){ + public void selectKey(long masterKeyId) { Uri buildUri = KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(masterKeyId)); - mReceivedUri=buildUri; + mReceivedUri = buildUri; getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index a43debd07..3ff88aa2b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package org.sufficientlysecure.keychain.ui.dialog; import android.app.AlertDialog; @@ -32,6 +33,7 @@ import android.view.View; import android.widget.CheckBox; import android.widget.LinearLayout; import android.widget.TextView; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; @@ -39,11 +41,12 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.Log; + import java.util.ArrayList; public class DeleteKeyDialogFragment extends DialogFragment { private static final String ARG_MESSENGER = "messenger"; - private static final String ARG_DELETE_KEY_RING_ROW_IDS = "delete_file"; + private static final String ARG_DELETE_KEY_RING_ROW_IDS = "delete_key_ring_row_ids"; public static final int MESSAGE_OKAY = 1; public static final int MESSAGE_ERROR = 0; @@ -131,74 +134,74 @@ public class DeleteKeyDialogFragment extends DialogFragment { builder.setIcon(R.drawable.ic_dialog_alert_holo_light); builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Uri queryUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri(); - String[] projection = new String[]{ - KeychainContract.KeyRings.MASTER_KEY_ID, // 0 - KeychainContract.KeyRings.TYPE// 1 - }; - - // make selection with all entries where _ID is one of the given row ids - String selection = KeychainDatabase.Tables.KEY_RINGS + "." + - KeychainContract.KeyRings._ID + " IN("; - String selectionIDs = ""; - for (int i = 0; i < keyRingRowIds.length; i++) { - selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'"; - if (i + 1 < keyRingRowIds.length) - selectionIDs += ","; - } - selection += selectionIDs + ")"; - - Cursor cursor = activity.getContentResolver().query(queryUri, projection, - selection, null, null); - + @Override + public void onClick(DialogInterface dialog, int which) { + Uri queryUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri(); + String[] projection = new String[]{ + KeychainContract.KeyRings.MASTER_KEY_ID, // 0 + KeychainContract.KeyRings.TYPE// 1 + }; + + // make selection with all entries where _ID is one of the given row ids + String selection = KeychainDatabase.Tables.KEY_RINGS + "." + + KeychainContract.KeyRings._ID + " IN("; + String selectionIDs = ""; + for (int i = 0; i < keyRingRowIds.length; i++) { + selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'"; + if (i + 1 < keyRingRowIds.length) + selectionIDs += ","; + } + selection += selectionIDs + ")"; - long masterKeyId; - long keyType; - boolean isSuccessfullyDeleted; - try { - isSuccessfullyDeleted = false; - while (cursor != null && cursor.moveToNext()) { - masterKeyId = cursor.getLong(0); - keyType = cursor.getLong(1); + Cursor cursor = activity.getContentResolver().query(queryUri, projection, + selection, null, null); - Log.d(Constants.TAG, "masterKeyId: " + masterKeyId - + ", keyType:" + (keyType == KeychainContract.KeyTypes.PUBLIC ? "Public" : "Private")); + long masterKeyId; + long keyType; + boolean isSuccessfullyDeleted; + try { + isSuccessfullyDeleted = false; + while (cursor != null && cursor.moveToNext()) { + masterKeyId = cursor.getLong(0); + keyType = cursor.getLong(1); - if (keyType == KeychainContract.KeyTypes.SECRET) { - if (checkDeleteSecret.isChecked() || isSingleSelection) { - ProviderHelper.deleteUnifiedKeyRing(activity, String.valueOf(masterKeyId), true); - } - } else { - ProviderHelper.deleteUnifiedKeyRing(activity, String.valueOf(masterKeyId), false); - } - } + Log.d(Constants.TAG, "masterKeyId: " + masterKeyId + + ", keyType:" + (keyType == KeychainContract.KeyTypes.PUBLIC ? "Public" : "Private")); - //Check if the selected rows have actually been deleted - cursor = activity.getContentResolver().query(queryUri, projection, selection, null, null); - if (cursor == null || cursor.getCount() == 0 || !checkDeleteSecret.isChecked()) { - isSuccessfullyDeleted = true; - } - } finally { - if (cursor != null) { - cursor.close(); + if (keyType == KeychainContract.KeyTypes.SECRET) { + if (checkDeleteSecret.isChecked() || isSingleSelection) { + ProviderHelper.deleteUnifiedKeyRing(activity, String.valueOf(masterKeyId), true); } - + } else { + ProviderHelper.deleteUnifiedKeyRing(activity, String.valueOf(masterKeyId), false); } + } - dismiss(); + //Check if the selected rows have actually been deleted + cursor = activity.getContentResolver().query(queryUri, projection, selection, null, null); + if (cursor == null || cursor.getCount() == 0 || !checkDeleteSecret.isChecked()) { + isSuccessfullyDeleted = true; + } - if (isSuccessfullyDeleted) { - sendMessageToHandler(MESSAGE_OKAY, null); - } else { - sendMessageToHandler(MESSAGE_ERROR, null); - } + } finally { + if (cursor != null) { + cursor.close(); } } + + dismiss(); + + if (isSuccessfullyDeleted) { + sendMessageToHandler(MESSAGE_OKAY, null); + } else { + sendMessageToHandler(MESSAGE_ERROR, null); + } + } + + } ); builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { -- cgit v1.2.3 From 1b57a10bb6a65a1900c79c68efe4c320177485da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 21 Mar 2014 11:26:18 +0100 Subject: Fix nfc help button --- .../java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java index 44b5848d8..110647284 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java @@ -57,7 +57,7 @@ public class ImportKeysNFCFragment extends Fragment { public void onClick(View v) { // show nfc help Intent intent = new Intent(getActivity(), HelpActivity.class); - intent.putExtra(HelpActivity.EXTRA_SELECTED_TAB, 1); + intent.putExtra(HelpActivity.EXTRA_SELECTED_TAB, 2); startActivityForResult(intent, 0); } }); -- cgit v1.2.3 From b7bc8faee6e9500287baf86a6bb4fe42be80ef0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 21 Mar 2014 11:43:30 +0100 Subject: raname to mKeychainDatabase --- .../keychain/provider/KeychainProvider.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index b963ceb39..746449f7e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -247,7 +247,7 @@ public class KeychainProvider extends ContentProvider { return matcher; } - private KeychainDatabase mApgDatabase; + private KeychainDatabase mKeychainDatabase; /** * {@inheritDoc} @@ -255,7 +255,7 @@ public class KeychainProvider extends ContentProvider { @Override public boolean onCreate() { mUriMatcher = buildUriMatcher(); - mApgDatabase = new KeychainDatabase(getContext()); + mKeychainDatabase = new KeychainDatabase(getContext()); return true; } @@ -486,7 +486,7 @@ public class KeychainProvider extends ContentProvider { Log.v(Constants.TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")"); SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); - SQLiteDatabase db = mApgDatabase.getReadableDatabase(); + SQLiteDatabase db = mKeychainDatabase.getReadableDatabase(); int match = mUriMatcher.match(uri); @@ -715,7 +715,7 @@ public class KeychainProvider extends ContentProvider { public Uri insert(Uri uri, ContentValues values) { Log.d(Constants.TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")"); - final SQLiteDatabase db = mApgDatabase.getWritableDatabase(); + final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase(); Uri rowUri = null; long rowId = -1; @@ -792,7 +792,7 @@ public class KeychainProvider extends ContentProvider { public int delete(Uri uri, String selection, String[] selectionArgs) { Log.v(Constants.TAG, "delete(uri=" + uri + ")"); - final SQLiteDatabase db = mApgDatabase.getWritableDatabase(); + final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase(); int count; final int match = mUriMatcher.match(uri); @@ -853,7 +853,7 @@ public class KeychainProvider extends ContentProvider { public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { Log.v(Constants.TAG, "update(uri=" + uri + ", values=" + values.toString() + ")"); - final SQLiteDatabase db = mApgDatabase.getWritableDatabase(); + final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase(); String defaultSelection = null; int count = 0; -- cgit v1.2.3 From 8f37569967c44f0693ba63541e4e6ecfe42aa73f Mon Sep 17 00:00:00 2001 From: uberspot Date: Fri, 21 Mar 2014 18:43:11 +0200 Subject: Make foldable settings in EncryptActivity a separate widget --- .../keychain/ui/EncryptActivity.java | 47 ----- .../keychain/ui/widget/FoldableLinearLayout.java | 203 +++++++++++++++++++++ 2 files changed, 203 insertions(+), 47 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 28c9c7b28..4ccfd393f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -108,11 +108,6 @@ public class EncryptActivity extends DrawerActivity { private String mInputFilename = null; private String mOutputFilename = null; - private Integer mShortAnimationDuration = null; - private boolean mFileAdvancedSettingsVisible = false; - private TextView mFileAdvancedSettings = null; - private LinearLayout mFileAdvancedSettingsContainer = null; - private FontAwesomeText mAdvancedSettingsIcon; private boolean mAsciiArmorDemand = false; private boolean mOverrideAsciiArmor = false; @@ -147,9 +142,6 @@ public class EncryptActivity extends DrawerActivity { updateMode(); updateActionBarButtons(); - - // retrieve and cache the system's short animation time - mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime); } /** @@ -795,49 +787,10 @@ public class EncryptActivity extends DrawerActivity { } }); - mAdvancedSettingsIcon = (FontAwesomeText) findViewById(R.id.advancedSettingsIcon); - mFileAdvancedSettingsContainer = (LinearLayout) findViewById(R.id.fileAdvancedSettingsContainer); - mFileAdvancedSettings = (TextView) findViewById(R.id.advancedSettings); - LinearLayout advancedSettingsControl = (LinearLayout) findViewById(R.id.advancedSettingsControl); - advancedSettingsControl.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - mFileAdvancedSettingsVisible = !mFileAdvancedSettingsVisible; - if (mFileAdvancedSettingsVisible) { - mAdvancedSettingsIcon.setIcon("fa-chevron-down"); - mFileAdvancedSettingsContainer.setVisibility(View.VISIBLE); - AlphaAnimation animation = new AlphaAnimation(0f, 1f); - animation.setDuration(mShortAnimationDuration); - mFileAdvancedSettingsContainer.startAnimation(animation); - mFileAdvancedSettings.setText(R.string.btn_encryption_advanced_settings_hide); - } else { - mAdvancedSettingsIcon.setIcon("fa-chevron-right"); - AlphaAnimation animation = new AlphaAnimation(1f, 0f); - animation.setDuration(mShortAnimationDuration); - animation.setAnimationListener(new Animation.AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - // do nothing - } - @Override - public void onAnimationEnd(Animation animation) { - // making sure that at the end the container is completely removed from view - mFileAdvancedSettingsContainer.setVisibility(View.GONE); - } - @Override - public void onAnimationRepeat(Animation animation) { - // do nothing - } - }); - mFileAdvancedSettingsContainer.startAnimation(animation); - mFileAdvancedSettings.setText(R.string.btn_encryption_advanced_settings_show); - } - } - }); mFileCompression = (Spinner) findViewById(R.id.fileCompression); Choice[] choices = new Choice[]{ diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java new file mode 100644 index 000000000..f9a5b92f3 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.ui.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.widget.LinearLayout; +import android.widget.TextView; +import com.beardedhen.androidbootstrap.FontAwesomeText; +import org.sufficientlysecure.keychain.R; + +/** + * Class representing a LinearLayout that can fold and hide it's content when pressed + * To use just add the following to your xml layout + + + + + + + + */ +public class FoldableLinearLayout extends LinearLayout { + + private FontAwesomeText mFoldableIcon; + private boolean mFolded; + private boolean mHasMigrated = false; + private Integer mShortAnimationDuration = null; + private TextView mFoldableTextView = null; + private LinearLayout mFoldableContainer = null; + private View mFoldableLayout = null; + + private String mFoldedIconName; + private String mUnFoldedIconName; + private String mFoldedLabel; + private String mUnFoldedLabel; + + public FoldableLinearLayout(Context context) { + super(context); + processAttributes(context, null); + } + + public FoldableLinearLayout(Context context, AttributeSet attrs) { + super(context, attrs); + processAttributes(context, attrs); + } + + public FoldableLinearLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs); + processAttributes(context, attrs); + } + + /** + * Load given attributes to inner variables, + * @param context + * @param attrs + */ + private void processAttributes(Context context, AttributeSet attrs) { + if(attrs != null) { + TypedArray a = context.obtainStyledAttributes(attrs, + R.styleable.FoldableLinearLayout, 0, 0); + mFoldedIconName = a.getString(R.styleable.FoldableLinearLayout_foldedIcon); + mUnFoldedIconName = a.getString(R.styleable.FoldableLinearLayout_unFoldedIcon); + mFoldedLabel = a.getString(R.styleable.FoldableLinearLayout_foldedLabel); + mUnFoldedLabel = a.getString(R.styleable.FoldableLinearLayout_unFoldedLabel); + a.recycle(); + } + // If any attribute isn't found then set a default one + mFoldedIconName = (mFoldedIconName == null) ? "fa-chevron-right" : mFoldedIconName; + mUnFoldedIconName = (mUnFoldedIconName == null) ? "fa-chevron-down" : mUnFoldedIconName; + mFoldedLabel = (mFoldedLabel == null) ? context.getString(R.id.none) : mFoldedLabel; + mUnFoldedLabel = (mUnFoldedLabel == null) ? context.getString(R.id.none) : mUnFoldedLabel; + } + + @Override + protected void onFinishInflate() { + // if the migration has already happened + // there is no need to move any children + if(!mHasMigrated) { + migrateChildrenToContainer(); + mHasMigrated = true; + } + + initialiseInnerViews(); + + super.onFinishInflate(); + } + + /** + * Migrates Child views as declared in xml to the inner foldableContainer + */ + private void migrateChildrenToContainer() { + // Collect children of FoldableLinearLayout as declared in XML + int childNum = getChildCount(); + View[] children = new View[childNum]; + + for(int i = 0; i < childNum; i++) { + children[i] = getChildAt(i); + } + if(children[0].getId() == R.id.foldableControl) { + + } + + // remove all of them from FoldableLinearLayout + detachAllViewsFromParent(); + + // Inflate the inner foldable_linearlayout.xml + LayoutInflater inflator = (LayoutInflater)getContext().getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + + mFoldableLayout = inflator.inflate(R.layout.foldable_linearlayout, this, true); + mFoldableContainer = (LinearLayout) mFoldableLayout.findViewById(R.id.foldableContainer); + + // Push previously collected children into foldableContainer. + for(int i = 0; i < childNum; i++) { + addView(children[i]); + } + } + + private void initialiseInnerViews() { + mFoldableIcon = (FontAwesomeText) mFoldableLayout.findViewById(R.id.foldableIcon); + mFoldableIcon.setIcon(mFoldedIconName); + mFoldableTextView = (TextView) mFoldableLayout.findViewById(R.id.foldableText); + mFoldableTextView.setText(mFoldedLabel); + + // retrieve and cache the system's short animation time + mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime); + + LinearLayout foldableControl = (LinearLayout) mFoldableLayout.findViewById(R.id.foldableControl); + foldableControl.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mFolded = !mFolded; + if (mFolded) { + mFoldableIcon.setIcon(mUnFoldedIconName); + mFoldableContainer.setVisibility(View.VISIBLE); + AlphaAnimation animation = new AlphaAnimation(0f, 1f); + animation.setDuration(mShortAnimationDuration); + mFoldableContainer.startAnimation(animation); + mFoldableTextView.setText(mUnFoldedLabel); + + } else { + mFoldableIcon.setIcon(mFoldedIconName); + AlphaAnimation animation = new AlphaAnimation(1f, 0f); + animation.setDuration(mShortAnimationDuration); + animation.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { } + + @Override + public void onAnimationEnd(Animation animation) { + // making sure that at the end the container is completely removed from view + mFoldableContainer.setVisibility(View.GONE); + } + + @Override + public void onAnimationRepeat(Animation animation) { } + }); + mFoldableContainer.startAnimation(animation); + mFoldableTextView.setText(mFoldedLabel); + } + } + }); + + } + + /** + * Adds provided child view to foldableContainer View + * @param child + */ + @Override + public void addView(View child) { + if(mFoldableContainer != null) { + mFoldableContainer.addView(child); + } + } +} -- cgit v1.2.3 From 0f6dc253a40ecada0c0c2a467c56ee45b7b9cc72 Mon Sep 17 00:00:00 2001 From: Daniel Hammann Date: Fri, 21 Mar 2014 23:01:24 +0100 Subject: Because of an unknown reason toast messages were commented out. --- .../sufficientlysecure/keychain/ui/EditKeyActivity.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 9b64def1e..092a502e1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -495,11 +495,10 @@ public class EditKeyActivity extends ActionBarActivity { private void saveClicked() { long masterKeyId = getMasterKeyId(); - try { - if (!isPassphraseSet()) { - throw new PgpGeneralException(this.getString(R.string.set_a_passphrase)); - } - + if (!isPassphraseSet()) { + Log.e(Constants.TAG, "No passphrase has been set"); + Toast.makeText(this, R.string.set_a_passphrase, Toast.LENGTH_LONG).show(); + } else { String passphrase = null; if (mIsPassPhraseSet) { passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId); @@ -512,9 +511,6 @@ public class EditKeyActivity extends ActionBarActivity { mCurrentPassphrase = passphrase; finallySaveClicked(); } - } catch (PgpGeneralException e) { - //Toast.makeText(this, getString(R.string.error_message, e.getMessage()), - // Toast.LENGTH_SHORT).show(); } } @@ -576,8 +572,9 @@ public class EditKeyActivity extends ActionBarActivity { // start service with intent startService(intent); } catch (PgpGeneralException e) { - //Toast.makeText(this, getString(R.string.error_message, e.getMessage()), - // Toast.LENGTH_SHORT).show(); + Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage())); + Toast.makeText(this, getString(R.string.error_message, e.getMessage()), + Toast.LENGTH_SHORT).show(); } } -- cgit v1.2.3 From 9c180629510d6b07aa296088f61593234b52a14a Mon Sep 17 00:00:00 2001 From: Daniel Hammann Date: Sat, 22 Mar 2014 15:31:18 +0100 Subject: The current implementation of saving new generated key doesn't save the key due to the public key of master key id can not be resolved by ProviderHelper.getPGPPublicKeyByKeyId (via URI/Cursor). Workaround uses local keys-arraylist for resoving the pubkey of master key id. --- .../keychain/service/KeychainIntentService.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 0751fa33c..e26ee3c76 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -543,7 +543,15 @@ public class KeychainIntentService extends IntentService ProviderHelper.getPGPSecretKeyRingByKeyId(this, masterKeyId), oldPassPhrase, newPassPhrase); } else { - PGPPublicKey pubkey = ProviderHelper.getPGPPublicKeyByKeyId(this, masterKeyId); + //TODO: Workaround due to ProviderHelper.getPGPPublicKeyByKeyId can not resolve public key of master-key id with uri/cursor + PGPPublicKey pubkey = null; + for(PGPSecretKey key : keys) { + PGPPublicKey tempKey = key.getPublicKey(); + if (tempKey.getKeyID() == masterKeyId) { + pubkey = tempKey; + } + } + //PGPPublicKey pubkey = ProviderHelper.getPGPPublicKeyByKeyId(this, masterKeyId); keyOperations.buildSecretKey(userIds, keys, keysUsages, keysExpiryDates, pubkey, oldPassPhrase, newPassPhrase); } -- cgit v1.2.3 From 153b99a186f514ff08f4b2a659202049f237c9fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 23 Mar 2014 00:03:49 +0100 Subject: Use new FoldableLinearLayout in API settings --- .../service/remote/AppSettingsFragment.java | 46 +++------------------- 1 file changed, 5 insertions(+), 41 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java index 837295018..52b06a2ae 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java @@ -25,13 +25,13 @@ import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; -import android.view.animation.AlphaAnimation; -import android.view.animation.Animation; -import android.widget.*; +import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; -import com.beardedhen.androidbootstrap.BootstrapButton; +import android.widget.ImageView; +import android.widget.Spinner; +import android.widget.TextView; + import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -50,8 +50,6 @@ public class AppSettingsFragment extends Fragment implements private AppSettings mAppSettings; // view - private LinearLayout mAdvancedSettingsContainer; - private BootstrapButton mAdvancedSettingsButton; private TextView mAppNameView; private ImageView mAppIconView; private Spinner mEncryptionAlgorithm; @@ -117,11 +115,6 @@ public class AppSettingsFragment extends Fragment implements R.id.api_app_settings_select_key_fragment); mSelectKeyFragment.setCallback(this); - mAdvancedSettingsButton = (BootstrapButton) view - .findViewById(R.id.api_app_settings_advanced_button); - mAdvancedSettingsContainer = (LinearLayout) view - .findViewById(R.id.api_app_settings_advanced); - mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name); mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon); mEncryptionAlgorithm = (Spinner) view @@ -176,35 +169,6 @@ public class AppSettingsFragment extends Fragment implements public void onNothingSelected(AdapterView parent) { } }); - - final Animation visibleAnimation = new AlphaAnimation(0.0f, 1.0f); - visibleAnimation.setDuration(250); - final Animation invisibleAnimation = new AlphaAnimation(1.0f, 0.0f); - invisibleAnimation.setDuration(250); - - // TODO: Better: collapse/expand animation - // final Animation animation2 = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, - // Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, -1.0f, - // Animation.RELATIVE_TO_SELF, 0.0f);u - // animation2.setDuration(150); - - mAdvancedSettingsButton.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (mAdvancedSettingsContainer.getVisibility() == View.VISIBLE) { - mAdvancedSettingsContainer.startAnimation(invisibleAnimation); - mAdvancedSettingsContainer.setVisibility(View.GONE); - mAdvancedSettingsButton.setText(getString(R.string.api_settings_show_advanced)); - mAdvancedSettingsButton.setLeftIcon("fa-caret-up"); - } else { - mAdvancedSettingsContainer.startAnimation(visibleAnimation); - mAdvancedSettingsContainer.setVisibility(View.VISIBLE); - mAdvancedSettingsButton.setText(getString(R.string.api_settings_hide_advanced)); - mAdvancedSettingsButton.setLeftIcon("fa-caret-down"); - } - } - }); } private void setPackage(String packageName) { -- cgit v1.2.3 From 12402d9a513e83755aa657acd29dd7382f355d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 23 Mar 2014 01:16:56 +0100 Subject: New db table for api accounts --- .../keychain/provider/KeychainContract.java | 4 ++++ .../keychain/provider/KeychainDatabase.java | 27 +++++++++++++++++----- 2 files changed, 25 insertions(+), 6 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index 5f2354c24..de51cebbb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -56,10 +56,14 @@ public class KeychainContract { interface ApiAppsColumns { String PACKAGE_NAME = "package_name"; String PACKAGE_SIGNATURE = "package_signature"; + } + + interface ApiAppsAccountsColumns { String KEY_ID = "key_id"; // not a database id String ENCRYPTION_ALGORITHM = "encryption_algorithm"; String HASH_ALORITHM = "hash_algorithm"; String COMPRESSION = "compression"; + String PACKAGE_NAME = "package_name"; // foreign key to api_apps.package_name } public static final class KeyTypes { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 031a7d5ae..f7c9fe79d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -23,6 +23,7 @@ import android.database.sqlite.SQLiteOpenHelper; import android.provider.BaseColumns; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns; @@ -30,13 +31,14 @@ import org.sufficientlysecure.keychain.util.Log; public class KeychainDatabase extends SQLiteOpenHelper { private static final String DATABASE_NAME = "apg.db"; - private static final int DATABASE_VERSION = 7; + private static final int DATABASE_VERSION = 8; public interface Tables { String KEY_RINGS = "key_rings"; String KEYS = "keys"; String USER_IDS = "user_ids"; String API_APPS = "api_apps"; + String API_APPS_ACCOUNTS = "api_apps_accounts"; } private static final String CREATE_KEY_RINGS = "CREATE TABLE IF NOT EXISTS " + Tables.KEY_RINGS @@ -76,11 +78,17 @@ public class KeychainDatabase extends SQLiteOpenHelper { private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + ApiAppsColumns.PACKAGE_NAME + " TEXT UNIQUE, " - + ApiAppsColumns.PACKAGE_SIGNATURE + " BLOB, " - + ApiAppsColumns.KEY_ID + " INT64, " - + ApiAppsColumns.ENCRYPTION_ALGORITHM + " INTEGER, " - + ApiAppsColumns.HASH_ALORITHM + " INTEGER, " - + ApiAppsColumns.COMPRESSION + " INTEGER)"; + + ApiAppsColumns.PACKAGE_SIGNATURE + " BLOB)"; + + private static final String CREATE_API_APPS_ACCOUNTS = "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS_ACCOUNTS + + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + + ApiAppsAccountsColumns.KEY_ID + " INT64, " + + ApiAppsAccountsColumns.ENCRYPTION_ALGORITHM + " INTEGER, " + + ApiAppsAccountsColumns.HASH_ALORITHM + " INTEGER, " + + ApiAppsAccountsColumns.COMPRESSION + " INTEGER" + + ApiAppsAccountsColumns.PACKAGE_NAME + " TEXT NOT NULL, FOREIGN KEY(" + + ApiAppsAccountsColumns.PACKAGE_NAME + ") REFERENCES " + Tables.API_APPS + "(" + + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE)"; KeychainDatabase(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); @@ -94,6 +102,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { db.execSQL(CREATE_KEYS); db.execSQL(CREATE_USER_IDS); db.execSQL(CREATE_API_APPS); + db.execSQL(CREATE_API_APPS_ACCOUNTS); } @Override @@ -133,6 +142,12 @@ public class KeychainDatabase extends SQLiteOpenHelper { db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.FINGERPRINT + " BLOB;"); break; + case 7: + // new db layout for api apps + db.execSQL("DROP TABLE IF EXISTS " + Tables.API_APPS); + db.execSQL(CREATE_API_APPS); + db.execSQL(CREATE_API_APPS_ACCOUNTS); + break; default: break; -- cgit v1.2.3 From 9555ae3bc1287daa27151456a1f266bdc1640e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 23 Mar 2014 01:26:49 +0100 Subject: Move classes for OpenPGP API into remote package --- .../keychain/provider/ProviderHelper.java | 10 +- .../keychain/remote/AppSettings.java | 94 +++++ .../keychain/remote/OpenPgpService.java | 463 +++++++++++++++++++++ .../keychain/remote/RemoteService.java | 233 +++++++++++ .../remote/WrongPackageSignatureException.java | 27 ++ .../keychain/remote/ui/AppSettingsActivity.java | 109 +++++ .../keychain/remote/ui/AppSettingsFragment.java | 202 +++++++++ .../keychain/remote/ui/RegisteredAppsAdapter.java | 75 ++++ .../remote/ui/RegisteredAppsListActivity.java | 35 ++ .../remote/ui/RegisteredAppsListFragment.java | 101 +++++ .../keychain/remote/ui/RemoteServiceActivity.java | 279 +++++++++++++ .../keychain/service/remote/AppSettings.java | 94 ----- .../service/remote/AppSettingsActivity.java | 108 ----- .../service/remote/AppSettingsFragment.java | 201 --------- .../keychain/service/remote/OpenPgpService.java | 462 -------------------- .../service/remote/RegisteredAppsAdapter.java | 75 ---- .../service/remote/RegisteredAppsListActivity.java | 35 -- .../service/remote/RegisteredAppsListFragment.java | 101 ----- .../keychain/service/remote/RemoteService.java | 232 ----------- .../service/remote/RemoteServiceActivity.java | 278 ------------- .../remote/WrongPackageSignatureException.java | 27 -- 21 files changed, 1623 insertions(+), 1618 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsAdapter.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListActivity.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListFragment.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettings.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsAdapter.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListActivity.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListFragment.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 2fa903fe2..e0d007de7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -33,7 +33,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; -import org.sufficientlysecure.keychain.service.remote.AppSettings; +import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; @@ -801,10 +801,10 @@ public class ProviderHelper { ContentValues values = new ContentValues(); values.put(ApiApps.PACKAGE_NAME, appSettings.getPackageName()); values.put(ApiApps.PACKAGE_SIGNATURE, appSettings.getPackageSignature()); - values.put(ApiApps.KEY_ID, appSettings.getKeyId()); - values.put(ApiApps.COMPRESSION, appSettings.getCompression()); - values.put(ApiApps.ENCRYPTION_ALGORITHM, appSettings.getEncryptionAlgorithm()); - values.put(ApiApps.HASH_ALORITHM, appSettings.getHashAlgorithm()); +// values.put(ApiApps.KEY_ID, appSettings.getKeyId()); +// values.put(ApiApps.COMPRESSION, appSettings.getCompression()); +// values.put(ApiApps.ENCRYPTION_ALGORITHM, appSettings.getEncryptionAlgorithm()); +// values.put(ApiApps.HASH_ALORITHM, appSettings.getHashAlgorithm()); return values; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java new file mode 100644 index 000000000..ad48a402b --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote; + +import org.spongycastle.bcpg.HashAlgorithmTags; +import org.spongycastle.openpgp.PGPEncryptedData; +import org.sufficientlysecure.keychain.Id; + +public class AppSettings { + private String mPackageName; + private byte[] mPackageSignature; + private long mKeyId = Id.key.none; + private int mEncryptionAlgorithm; + private int mHashAlgorithm; + private int mCompression; + + public AppSettings() { + + } + + public AppSettings(String packageName, byte[] packageSignature) { + super(); + this.mPackageName = packageName; + this.mPackageSignature = packageSignature; + // defaults: + this.mEncryptionAlgorithm = PGPEncryptedData.AES_256; + this.mHashAlgorithm = HashAlgorithmTags.SHA512; + this.mCompression = Id.choice.compression.zlib; + } + + public String getPackageName() { + return mPackageName; + } + + public void setPackageName(String packageName) { + this.mPackageName = packageName; + } + + public byte[] getPackageSignature() { + return mPackageSignature; + } + + public void setPackageSignature(byte[] packageSignature) { + this.mPackageSignature = packageSignature; + } + + public long getKeyId() { + return mKeyId; + } + + public void setKeyId(long scretKeyId) { + this.mKeyId = scretKeyId; + } + + public int getEncryptionAlgorithm() { + return mEncryptionAlgorithm; + } + + public void setEncryptionAlgorithm(int encryptionAlgorithm) { + this.mEncryptionAlgorithm = encryptionAlgorithm; + } + + public int getHashAlgorithm() { + return mHashAlgorithm; + } + + public void setHashAlgorithm(int hashAlgorithm) { + this.mHashAlgorithm = hashAlgorithm; + } + + public int getCompression() { + return mCompression; + } + + public void setCompression(int compression) { + this.mCompression = compression; + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java new file mode 100644 index 000000000..9b56a491a --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -0,0 +1,463 @@ +/* + * Copyright (C) 2013-2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote; + +import android.app.PendingIntent; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.IBinder; +import android.os.ParcelFileDescriptor; +import org.openintents.openpgp.IOpenPgpService; +import org.openintents.openpgp.OpenPgpError; +import org.openintents.openpgp.OpenPgpSignatureResult; +import org.openintents.openpgp.util.OpenPgpApi; +import org.spongycastle.util.Arrays; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Id; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; +import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity; +import org.sufficientlysecure.keychain.service.PassphraseCacheService; +import org.sufficientlysecure.keychain.util.InputData; +import org.sufficientlysecure.keychain.util.Log; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; + +public class OpenPgpService extends RemoteService { + + private static final int PRIVATE_REQUEST_CODE_PASSPHRASE = 551; + private static final int PRIVATE_REQUEST_CODE_USER_IDS = 552; + private static final int PRIVATE_REQUEST_CODE_GET_KEYS = 553; + + /** + * Search database for key ids based on emails. + * + * @param encryptionUserIds + * @return + */ + private Intent getKeyIdsFromEmails(Intent data, String[] encryptionUserIds) { + // find key ids to given emails in database + ArrayList keyIds = new ArrayList(); + + boolean missingUserIdsCheck = false; + boolean dublicateUserIdsCheck = false; + ArrayList missingUserIds = new ArrayList(); + ArrayList dublicateUserIds = new ArrayList(); + + for (String email : encryptionUserIds) { + Uri uri = KeychainContract.KeyRings.buildPublicKeyRingsByEmailsUri(email); + Cursor cur = getContentResolver().query(uri, null, null, null, null); + if (cur.moveToFirst()) { + long id = cur.getLong(cur.getColumnIndex(KeychainContract.KeyRings.MASTER_KEY_ID)); + keyIds.add(id); + } else { + missingUserIdsCheck = true; + missingUserIds.add(email); + Log.d(Constants.TAG, "user id missing"); + } + if (cur.moveToNext()) { + dublicateUserIdsCheck = true; + dublicateUserIds.add(email); + Log.d(Constants.TAG, "more than one user id with the same email"); + } + } + + // convert to long[] + long[] keyIdsArray = new long[keyIds.size()]; + for (int i = 0; i < keyIdsArray.length; i++) { + keyIdsArray[i] = keyIds.get(i); + } + + // allow the user to verify pub key selection + if (missingUserIdsCheck || dublicateUserIdsCheck) { + // build PendingIntent + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); + intent.setAction(RemoteServiceActivity.ACTION_SELECT_PUB_KEYS); + intent.putExtra(RemoteServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray); + intent.putExtra(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds); + intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, dublicateUserIds); + intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); + + PendingIntent pi = PendingIntent.getActivity + (getBaseContext(), PRIVATE_REQUEST_CODE_USER_IDS, intent, 0); + + // return PendingIntent to be executed by client + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_INTENT, pi); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); + return result; + } + + if (keyIdsArray.length == 0) { + return null; + } + + Intent result = new Intent(); + result.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keyIdsArray); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); + return result; + } + + private Intent getPassphraseBundleIntent(Intent data, long keyId) { + // build PendingIntent for passphrase input + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); + intent.setAction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE); + intent.putExtra(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, keyId); + // pass params through to activity that it can be returned again later to repeat pgp operation + intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); + PendingIntent pi = PendingIntent.getActivity + (getBaseContext(), PRIVATE_REQUEST_CODE_PASSPHRASE, intent, 0); + + // return PendingIntent to be executed by client + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_INTENT, pi); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); + return result; + } + + private Intent signImpl(Intent data, ParcelFileDescriptor input, + ParcelFileDescriptor output, AppSettings appSettings) { + try { + boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); + + // get passphrase from cache, if key has "no" passphrase, this returns an empty String + String passphrase; + if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) { + passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE); + } else { + passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); + } + if (passphrase == null) { + // get PendingIntent for passphrase input, add it to given params and return to client + Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId()); + return passphraseBundle; + } + + // Get Input- and OutputStream from ParcelFileDescriptor + InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); + OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output); + try { + long inputLength = is.available(); + InputData inputData = new InputData(is, inputLength); + + // sign-only + PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os); + builder.enableAsciiArmorOutput(asciiArmor) + .signatureHashAlgorithm(appSettings.getHashAlgorithm()) + .signatureForceV3(false) + .signatureKeyId(appSettings.getKeyId()) + .signaturePassphrase(passphrase); + builder.build().execute(); + } finally { + is.close(); + os.close(); + } + + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); + return result; + } catch (Exception e) { + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_ERROR, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); + return result; + } + } + + private Intent encryptAndSignImpl(Intent data, ParcelFileDescriptor input, + ParcelFileDescriptor output, AppSettings appSettings, boolean sign) { + try { + boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); + + long[] keyIds; + if (data.hasExtra(OpenPgpApi.EXTRA_KEY_IDS)) { + keyIds = data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS); + } else if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS)) { + // get key ids based on given user ids + String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS); + // give params through to activity... + Intent result = getKeyIdsFromEmails(data, userIds); + + if (result.getIntExtra(OpenPgpApi.RESULT_CODE, 0) == OpenPgpApi.RESULT_CODE_SUCCESS) { + keyIds = result.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS); + } else { + // if not success -> result contains a PendingIntent for user interaction + return result; + } + } else { + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_ERROR, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, + "Missing parameter user_ids or key_ids!")); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); + return result; + } + + // add own key for encryption + keyIds = Arrays.copyOf(keyIds, keyIds.length + 1); + keyIds[keyIds.length - 1] = appSettings.getKeyId(); + + // build InputData and write into OutputStream + // Get Input- and OutputStream from ParcelFileDescriptor + InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); + OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output); + try { + long inputLength = is.available(); + InputData inputData = new InputData(is, inputLength); + + PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os); + builder.enableAsciiArmorOutput(asciiArmor) + .compressionId(appSettings.getCompression()) + .symmetricEncryptionAlgorithm(appSettings.getEncryptionAlgorithm()) + .encryptionKeyIds(keyIds); + + if (sign) { + String passphrase; + if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) { + passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE); + } else { + passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), + appSettings.getKeyId()); + } + if (passphrase == null) { + // get PendingIntent for passphrase input, add it to given params and return to client + Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId()); + return passphraseBundle; + } + + // sign and encrypt + builder.signatureHashAlgorithm(appSettings.getHashAlgorithm()) + .signatureForceV3(false) + .signatureKeyId(appSettings.getKeyId()) + .signaturePassphrase(passphrase); + } else { + // encrypt only + builder.signatureKeyId(Id.key.none); + } + // execute PGP operation! + builder.build().execute(); + } finally { + is.close(); + os.close(); + } + + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); + return result; + } catch (Exception e) { + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_ERROR, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); + return result; + } + } + + private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input, + ParcelFileDescriptor output, AppSettings appSettings) { + try { + // Get Input- and OutputStream from ParcelFileDescriptor + InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); + OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output); + + Intent result = new Intent(); + try { + + String passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE); + long inputLength = is.available(); + InputData inputData = new InputData(is, inputLength); + + PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os); + builder.assumeSymmetric(false) // no support for symmetric encryption + // allow only the private key for this app for decryption + .enforcedKeyId(appSettings.getKeyId()) + .passphrase(passphrase); + + // TODO: currently does not support binary signed-only content + PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute(); + + if (decryptVerifyResult.isKeyPassphraseNeeded()) { + // get PendingIntent for passphrase input, add it to given params and return to client + Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId()); + return passphraseBundle; + } else if (decryptVerifyResult.isSymmetricPassphraseNeeded()) { + throw new PgpGeneralException("Decryption of symmetric content not supported by API!"); + } + + OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); + if (signatureResult != null) { + if (signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY) { + // If signature is unknown we return an _additional_ PendingIntent + // to retrieve the missing key + // TODO!!! + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); + intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE); + intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo"); + intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); + + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), + PRIVATE_REQUEST_CODE_GET_KEYS, intent, 0); + + result.putExtra(OpenPgpApi.RESULT_INTENT, pi); + } + + result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult); + } + + } finally { + is.close(); + os.close(); + } + + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); + return result; + } catch (Exception e) { + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_ERROR, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); + return result; + } + } + + private Intent getKeyImpl(Intent data) { + try { + long keyId = data.getLongExtra(OpenPgpApi.EXTRA_KEY_ID, 0); + + if (ProviderHelper.getPGPPublicKeyByKeyId(this, keyId) == null) { + Intent result = new Intent(); + + // If keys are not in db we return an additional PendingIntent + // to retrieve the missing key + // TODO!!! + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); + intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE); + intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo"); + intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); + + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), + PRIVATE_REQUEST_CODE_GET_KEYS, intent, 0); + + result.putExtra(OpenPgpApi.RESULT_INTENT, pi); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); + return result; + } else { + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); + return result; + } + } catch (Exception e) { + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_ERROR, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); + return result; + } + } + + private Intent getKeyIdsImpl(Intent data) { + // get key ids based on given user ids + String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS); + Intent result = getKeyIdsFromEmails(data, userIds); + return result; + } + + /** + * Check requirements: + * - params != null + * - has supported API version + * - is allowed to call the service (access has been granted) + * + * @param data + * @return null if everything is okay, or a Bundle with an error/PendingIntent + */ + private Intent checkRequirements(Intent data) { + // params Bundle is required! + if (data == null) { + Intent result = new Intent(); + OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!"); + result.putExtra(OpenPgpApi.RESULT_ERROR, error); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); + return result; + } + + // version code is required and needs to correspond to version code of service! + if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != OpenPgpApi.API_VERSION) { + Intent result = new Intent(); + OpenPgpError error = new OpenPgpError + (OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!"); + result.putExtra(OpenPgpApi.RESULT_ERROR, error); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); + return result; + } + + // check if caller is allowed to access openpgp keychain + Intent result = isAllowed(data); + if (result != null) { + return result; + } + + return null; + } + + // TODO: multi-threading + private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() { + + @Override + public Intent execute(Intent data, ParcelFileDescriptor input, ParcelFileDescriptor output) { + Intent errorResult = checkRequirements(data); + if (errorResult != null) { + return errorResult; + } + + final AppSettings appSettings = getAppSettings(); + + String action = data.getAction(); + if (OpenPgpApi.ACTION_SIGN.equals(action)) { + return signImpl(data, input, output, appSettings); + } else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) { + return encryptAndSignImpl(data, input, output, appSettings, false); + } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) { + return encryptAndSignImpl(data, input, output, appSettings, true); + } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) { + return decryptAndVerifyImpl(data, input, output, appSettings); + } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) { + return getKeyImpl(data); + } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) { + return getKeyIdsImpl(data); + } else { + return null; + } + } + + }; + + @Override + public IBinder onBind(Intent intent) { + return mBinder; + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java new file mode 100644 index 000000000..434fe84c1 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2013-2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote; + +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.Signature; +import android.net.Uri; +import android.os.Binder; +import org.openintents.openpgp.OpenPgpError; +import org.openintents.openpgp.util.OpenPgpApi; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity; +import org.sufficientlysecure.keychain.util.Log; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * Abstract service class for remote APIs that handle app registration and user input. + */ +public abstract class RemoteService extends Service { + Context mContext; + + private static final int PRIVATE_REQUEST_CODE_REGISTER = 651; + private static final int PRIVATE_REQUEST_CODE_ERROR = 652; + + + public Context getContext() { + return mContext; + } + + protected Intent isAllowed(Intent data) { + try { + if (isCallerAllowed(false)) { + + return null; + } else { + String[] callingPackages = getPackageManager().getPackagesForUid( + Binder.getCallingUid()); + // TODO: currently simply uses first entry + String packageName = callingPackages[0]; + + byte[] packageSignature; + try { + packageSignature = getPackageSignature(packageName); + } catch (NameNotFoundException e) { + Log.e(Constants.TAG, "Should not happen, returning!", e); + // return error + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); + result.putExtra(OpenPgpApi.RESULT_ERROR, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); + return result; + } + Log.e(Constants.TAG, "Not allowed to use service! return PendingIntent for registration!"); + + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); + intent.setAction(RemoteServiceActivity.ACTION_REGISTER); + intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName); + intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature); + intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); + + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), + PRIVATE_REQUEST_CODE_REGISTER, intent, 0); + + // return PendingIntent to be executed by client + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); + result.putExtra(OpenPgpApi.RESULT_INTENT, pi); + + return result; + } + } catch (WrongPackageSignatureException e) { + Log.e(Constants.TAG, "wrong signature!", e); + + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); + intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE); + intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, + getString(R.string.api_error_wrong_signature)); + intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); + + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), + PRIVATE_REQUEST_CODE_ERROR, intent, 0); + + // return PendingIntent to be executed by client + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); + result.putExtra(OpenPgpApi.RESULT_INTENT, pi); + + return result; + } + } + + private byte[] getPackageSignature(String packageName) throws NameNotFoundException { + PackageInfo pkgInfo = getPackageManager().getPackageInfo(packageName, + PackageManager.GET_SIGNATURES); + Signature[] signatures = pkgInfo.signatures; + // TODO: Only first signature?! + byte[] packageSignature = signatures[0].toByteArray(); + + return packageSignature; + } + + /** + * Retrieves AppSettings from database for the application calling this remote service + * + * @return + */ + protected AppSettings getAppSettings() { + String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid()); + + // get app settings for this package + for (int i = 0; i < callingPackages.length; i++) { + String currentPkg = callingPackages[i]; + + Uri uri = KeychainContract.ApiApps.buildByPackageNameUri(currentPkg); + + AppSettings settings = ProviderHelper.getApiAppSettings(this, uri); + + if (settings != null) { + return settings; + } + } + + return null; + } + + /** + * Checks if process that binds to this service (i.e. the package name corresponding to the + * process) is in the list of allowed package names. + * + * @param allowOnlySelf allow only Keychain app itself + * @return true if process is allowed to use this service + * @throws WrongPackageSignatureException + */ + private boolean isCallerAllowed(boolean allowOnlySelf) throws WrongPackageSignatureException { + return isUidAllowed(Binder.getCallingUid(), allowOnlySelf); + } + + private boolean isUidAllowed(int uid, boolean allowOnlySelf) + throws WrongPackageSignatureException { + if (android.os.Process.myUid() == uid) { + return true; + } + if (allowOnlySelf) { // barrier + return false; + } + + String[] callingPackages = getPackageManager().getPackagesForUid(uid); + + // is calling package allowed to use this service? + for (int i = 0; i < callingPackages.length; i++) { + String currentPkg = callingPackages[i]; + + if (isPackageAllowed(currentPkg)) { + return true; + } + } + + Log.d(Constants.TAG, "Caller is NOT allowed!"); + return false; + } + + /** + * Checks if packageName is a registered app for the API. Does not return true for own package! + * + * @param packageName + * @return + * @throws WrongPackageSignatureException + */ + private boolean isPackageAllowed(String packageName) throws WrongPackageSignatureException { + Log.d(Constants.TAG, "packageName: " + packageName); + + ArrayList allowedPkgs = ProviderHelper.getRegisteredApiApps(this); + Log.d(Constants.TAG, "allowed: " + allowedPkgs); + + // check if package is allowed to use our service + if (allowedPkgs.contains(packageName)) { + Log.d(Constants.TAG, "Package is allowed! packageName: " + packageName); + + // check package signature + byte[] currentSig; + try { + currentSig = getPackageSignature(packageName); + } catch (NameNotFoundException e) { + throw new WrongPackageSignatureException(e.getMessage()); + } + + byte[] storedSig = ProviderHelper.getApiAppSignature(this, packageName); + if (Arrays.equals(currentSig, storedSig)) { + Log.d(Constants.TAG, + "Package signature is correct! (equals signature from database)"); + return true; + } else { + throw new WrongPackageSignatureException( + "PACKAGE NOT ALLOWED! Signature wrong! (Signature not equals signature from database)"); + } + } + + return false; + } + + @Override + public void onCreate() { + super.onCreate(); + mContext = this; + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java new file mode 100644 index 000000000..6f44a65e9 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote; + +public class WrongPackageSignatureException extends Exception { + + private static final long serialVersionUID = -8294642703122196028L; + + public WrongPackageSignatureException(String message) { + super(message); + } +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java new file mode 100644 index 000000000..d544455ec --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.support.v7.app.ActionBarActivity; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.ActionBarHelper; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.remote.AppSettings; +import org.sufficientlysecure.keychain.util.Log; + +public class AppSettingsActivity extends ActionBarActivity { + private Uri mAppUri; + + private AppSettingsFragment mSettingsFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Inflate a "Done" custom action bar + ActionBarHelper.setOneButtonView(getSupportActionBar(), + R.string.api_settings_save, R.drawable.ic_action_done, + new View.OnClickListener() { + @Override + public void onClick(View v) { + // "Done" + save(); + } + }); + + setContentView(R.layout.api_app_settings_activity); + + mSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( + R.id.api_app_settings_fragment); + + Intent intent = getIntent(); + mAppUri = intent.getData(); + if (mAppUri == null) { + Log.e(Constants.TAG, "Intent data missing. Should be Uri of app!"); + finish(); + return; + } else { + Log.d(Constants.TAG, "uri: " + mAppUri); + loadData(mAppUri); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + getMenuInflater().inflate(R.menu.api_app_settings, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_api_settings_revoke: + revokeAccess(); + return true; + case R.id.menu_api_settings_cancel: + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + private void loadData(Uri appUri) { + AppSettings settings = ProviderHelper.getApiAppSettings(this, appUri); + mSettingsFragment.setAppSettings(settings); + } + + private void revokeAccess() { + if (getContentResolver().delete(mAppUri, null, null) <= 0) { + throw new RuntimeException(); + } + finish(); + } + + private void save() { + ProviderHelper.updateApiApp(this, mSettingsFragment.getAppSettings(), mAppUri); + + finish(); + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java new file mode 100644 index 000000000..8e8f3827b --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2013-2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.ImageView; +import android.widget.Spinner; +import android.widget.TextView; + +import org.spongycastle.util.encoders.Hex; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.remote.AppSettings; +import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; +import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter; +import org.sufficientlysecure.keychain.util.AlgorithmNames; +import org.sufficientlysecure.keychain.util.Log; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class AppSettingsFragment extends Fragment implements + SelectSecretKeyLayoutFragment.SelectSecretKeyCallback { + + // model + private AppSettings mAppSettings; + + // view + private TextView mAppNameView; + private ImageView mAppIconView; + private Spinner mEncryptionAlgorithm; + private Spinner mHashAlgorithm; + private Spinner mCompression; + private TextView mPackageName; + private TextView mPackageSignature; + + private SelectSecretKeyLayoutFragment mSelectKeyFragment; + + KeyValueSpinnerAdapter mEncryptionAdapter; + KeyValueSpinnerAdapter mHashAdapter; + KeyValueSpinnerAdapter mCompressionAdapter; + + public AppSettings getAppSettings() { + return mAppSettings; + } + + public void setAppSettings(AppSettings appSettings) { + this.mAppSettings = appSettings; + setPackage(appSettings.getPackageName()); + mPackageName.setText(appSettings.getPackageName()); + + try { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + md.update(appSettings.getPackageSignature()); + byte[] digest = md.digest(); + String signature = new String(Hex.encode(digest)); + + mPackageSignature.setText(signature); + } catch (NoSuchAlgorithmException e) { + Log.e(Constants.TAG, "Should not happen!", e); + } + + mSelectKeyFragment.selectKey(appSettings.getKeyId()); + mEncryptionAlgorithm.setSelection(mEncryptionAdapter.getPosition(appSettings + .getEncryptionAlgorithm())); + mHashAlgorithm.setSelection(mHashAdapter.getPosition(appSettings.getHashAlgorithm())); + mCompression.setSelection(mCompressionAdapter.getPosition(appSettings.getCompression())); + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.api_app_settings_fragment, container, false); + initView(view); + return view; + } + + /** + * Set error String on key selection + * + * @param error + */ + public void setErrorOnSelectKeyFragment(String error) { + mSelectKeyFragment.setError(error); + } + + private void initView(View view) { + mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getFragmentManager().findFragmentById( + R.id.api_app_settings_select_key_fragment); + mSelectKeyFragment.setCallback(this); + + mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name); + mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon); + mEncryptionAlgorithm = (Spinner) view + .findViewById(R.id.api_app_settings_encryption_algorithm); + mHashAlgorithm = (Spinner) view.findViewById(R.id.api_app_settings_hash_algorithm); + mCompression = (Spinner) view.findViewById(R.id.api_app_settings_compression); + mPackageName = (TextView) view.findViewById(R.id.api_app_settings_package_name); + mPackageSignature = (TextView) view.findViewById(R.id.api_app_settings_package_signature); + + AlgorithmNames algorithmNames = new AlgorithmNames(getActivity()); + + mEncryptionAdapter = new KeyValueSpinnerAdapter(getActivity(), + algorithmNames.getEncryptionNames()); + mEncryptionAlgorithm.setAdapter(mEncryptionAdapter); + mEncryptionAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() { + + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + mAppSettings.setEncryptionAlgorithm((int) id); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + + mHashAdapter = new KeyValueSpinnerAdapter(getActivity(), algorithmNames.getHashNames()); + mHashAlgorithm.setAdapter(mHashAdapter); + mHashAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() { + + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + mAppSettings.setHashAlgorithm((int) id); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + + mCompressionAdapter = new KeyValueSpinnerAdapter(getActivity(), + algorithmNames.getCompressionNames()); + mCompression.setAdapter(mCompressionAdapter); + mCompression.setOnItemSelectedListener(new OnItemSelectedListener() { + + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + mAppSettings.setCompression((int) id); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + } + + private void setPackage(String packageName) { + PackageManager pm = getActivity().getApplicationContext().getPackageManager(); + + // get application name and icon from package manager + String appName = null; + Drawable appIcon = null; + try { + ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); + + appName = (String) pm.getApplicationLabel(ai); + appIcon = pm.getApplicationIcon(ai); + } catch (final NameNotFoundException e) { + // fallback + appName = packageName; + } + mAppNameView.setText(appName); + mAppIconView.setImageDrawable(appIcon); + } + + /** + * callback from select secret key fragment + */ + @Override + public void onKeySelected(long secretKeyId) { + mAppSettings.setKeyId(secretKeyId); + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsAdapter.java new file mode 100644 index 000000000..c846343ab --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsAdapter.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.database.Cursor; +import android.support.v4.widget.CursorAdapter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; + +public class RegisteredAppsAdapter extends CursorAdapter { + + private LayoutInflater mInflater; + private PackageManager mPM; + + public RegisteredAppsAdapter(Context context, Cursor c, int flags) { + super(context, c, flags); + + mInflater = LayoutInflater.from(context); + mPM = context.getApplicationContext().getPackageManager(); + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name); + ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon); + + String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME)); + if (packageName != null) { + // get application name + try { + ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0); + + text.setText(mPM.getApplicationLabel(ai)); + icon.setImageDrawable(mPM.getApplicationIcon(ai)); + } catch (final NameNotFoundException e) { + // fallback + text.setText(packageName); + } + } else { + // fallback + text.setText(packageName); + } + + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return mInflater.inflate(R.layout.api_apps_adapter_list_item, null); + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListActivity.java new file mode 100644 index 000000000..79b3c8abc --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListActivity.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.os.Bundle; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.DrawerActivity; + +public class RegisteredAppsListActivity extends DrawerActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.api_apps_list_activity); + + setupDrawerNavigation(savedInstanceState); + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListFragment.java new file mode 100644 index 000000000..99e73e510 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListFragment.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.content.ContentUris; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.ListFragment; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; + +public class RegisteredAppsListFragment extends ListFragment implements + LoaderManager.LoaderCallbacks { + + // This is the Adapter being used to display the list's data. + RegisteredAppsAdapter mAdapter; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + getListView().setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int position, long id) { + // edit app settings + Intent intent = new Intent(getActivity(), AppSettingsActivity.class); + intent.setData(ContentUris.withAppendedId(KeychainContract.ApiApps.CONTENT_URI, id)); + startActivity(intent); + } + }); + + // Give some text to display if there is no data. In a real + // application this would come from a resource. + setEmptyText(getString(R.string.api_no_apps)); + + // We have a menu item to show in action bar. + setHasOptionsMenu(true); + + // Create an empty adapter we will use to display the loaded data. + mAdapter = new RegisteredAppsAdapter(getActivity(), null, 0); + setListAdapter(mAdapter); + + // Prepare the loader. Either re-connect with an existing one, + // or start a new one. + getLoaderManager().initLoader(0, null, this); + } + + // These are the Contacts rows that we will retrieve. + static final String[] PROJECTION = new String[]{ApiApps._ID, ApiApps.PACKAGE_NAME}; + + public Loader onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + // First, pick the base URI to use depending on whether we are + // currently filtering. + Uri baseUri = ApiApps.CONTENT_URI; + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null, + ApiApps.PACKAGE_NAME + " COLLATE LOCALIZED ASC"); + } + + public void onLoadFinished(Loader loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mAdapter.swapCursor(data); + } + + public void onLoaderReset(Loader loader) { + // This is called when the last Cursor provided to onLoadFinished() + // above is about to be closed. We need to make sure we are no + // longer using it. + mAdapter.swapCursor(null); + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java new file mode 100644 index 000000000..3e19a8ef6 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2013-2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; +import android.support.v7.app.ActionBarActivity; +import android.view.View; +import org.openintents.openpgp.util.OpenPgpApi; +import org.sufficientlysecure.htmltextview.HtmlTextView; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Id; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.ActionBarHelper; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.remote.AppSettings; +import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment; +import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; +import org.sufficientlysecure.keychain.util.Log; + +import java.util.ArrayList; + +public class RemoteServiceActivity extends ActionBarActivity { + + public static final String ACTION_REGISTER = Constants.INTENT_PREFIX + "API_ACTIVITY_REGISTER"; + public static final String ACTION_CACHE_PASSPHRASE = Constants.INTENT_PREFIX + + "API_ACTIVITY_CACHE_PASSPHRASE"; + public static final String ACTION_SELECT_PUB_KEYS = Constants.INTENT_PREFIX + + "API_ACTIVITY_SELECT_PUB_KEYS"; + public static final String ACTION_ERROR_MESSAGE = Constants.INTENT_PREFIX + + "API_ACTIVITY_ERROR_MESSAGE"; + + public static final String EXTRA_MESSENGER = "messenger"; + + public static final String EXTRA_DATA = "data"; + + // passphrase action + public static final String EXTRA_SECRET_KEY_ID = "secret_key_id"; + // register action + public static final String EXTRA_PACKAGE_NAME = "package_name"; + public static final String EXTRA_PACKAGE_SIGNATURE = "package_signature"; + // select pub keys action + public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "master_key_ids"; + public static final String EXTRA_MISSING_USER_IDS = "missing_user_ids"; + public static final String EXTRA_DUBLICATE_USER_IDS = "dublicate_user_ids"; + // error message + public static final String EXTRA_ERROR_MESSAGE = "error_message"; + + // register view + private AppSettingsFragment mSettingsFragment; + // select pub keys view + private SelectPublicKeyFragment mSelectFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + handleActions(getIntent(), savedInstanceState); + } + + protected void handleActions(Intent intent, Bundle savedInstanceState) { + + String action = intent.getAction(); + final Bundle extras = intent.getExtras(); + + + if (ACTION_REGISTER.equals(action)) { + final String packageName = extras.getString(EXTRA_PACKAGE_NAME); + final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE); + + // Inflate a "Done"/"Cancel" custom action bar view + ActionBarHelper.setTwoButtonView(getSupportActionBar(), + R.string.api_register_allow, R.drawable.ic_action_done, + new View.OnClickListener() { + @Override + public void onClick(View v) { + // Allow + + // user needs to select a key! + if (mSettingsFragment.getAppSettings().getKeyId() == Id.key.none) { + mSettingsFragment.setErrorOnSelectKeyFragment( + getString(R.string.api_register_error_select_key)); + } else { + ProviderHelper.insertApiApp(RemoteServiceActivity.this, + mSettingsFragment.getAppSettings()); + + // give data through for new service call + Intent resultData = extras.getParcelable(EXTRA_DATA); + RemoteServiceActivity.this.setResult(RESULT_OK, resultData); + RemoteServiceActivity.this.finish(); + } + } + }, R.string.api_register_disallow, R.drawable.ic_action_cancel, + new View.OnClickListener() { + @Override + public void onClick(View v) { + // Disallow + RemoteServiceActivity.this.setResult(RESULT_CANCELED); + RemoteServiceActivity.this.finish(); + } + } + ); + + setContentView(R.layout.api_app_register_activity); + + mSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( + R.id.api_app_settings_fragment); + + AppSettings settings = new AppSettings(packageName, packageSignature); + mSettingsFragment.setAppSettings(settings); + } else if (ACTION_CACHE_PASSPHRASE.equals(action)) { + long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID); + Intent resultData = extras.getParcelable(EXTRA_DATA); + + showPassphraseDialog(resultData, secretKeyId); + } else if (ACTION_SELECT_PUB_KEYS.equals(action)) { + long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS); + ArrayList missingUserIds = intent + .getStringArrayListExtra(EXTRA_MISSING_USER_IDS); + ArrayList dublicateUserIds = intent + .getStringArrayListExtra(EXTRA_DUBLICATE_USER_IDS); + + // TODO: do this with spannable instead of HTML to prevent parsing failures with weird user ids + String text = "" + getString(R.string.api_select_pub_keys_text) + ""; + text += "

"; + if (missingUserIds != null && missingUserIds.size() > 0) { + text += getString(R.string.api_select_pub_keys_missing_text); + text += "
"; + text += "

    "; + for (String userId : missingUserIds) { + text += "
  • " + userId + "
  • "; + } + text += "
"; + text += "
"; + } + if (dublicateUserIds != null && dublicateUserIds.size() > 0) { + text += getString(R.string.api_select_pub_keys_dublicates_text); + text += "
"; + text += "
    "; + for (String userId : dublicateUserIds) { + text += "
  • " + userId + "
  • "; + } + text += "
"; + } + + // Inflate a "Done"/"Cancel" custom action bar view + ActionBarHelper.setTwoButtonView(getSupportActionBar(), + R.string.btn_okay, R.drawable.ic_action_done, + new View.OnClickListener() { + @Override + public void onClick(View v) { + // add key ids to params Bundle for new request + Intent resultData = extras.getParcelable(EXTRA_DATA); + resultData.putExtra(OpenPgpApi.EXTRA_KEY_IDS, + mSelectFragment.getSelectedMasterKeyIds()); + + RemoteServiceActivity.this.setResult(RESULT_OK, resultData); + RemoteServiceActivity.this.finish(); + } + }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() { + @Override + public void onClick(View v) { + // cancel + RemoteServiceActivity.this.setResult(RESULT_CANCELED); + RemoteServiceActivity.this.finish(); + } + } + ); + + setContentView(R.layout.api_app_select_pub_keys_activity); + + // set text on view + HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_select_pub_keys_text); + textView.setHtmlFromString(text); + + /* Load select pub keys fragment */ + // Check that the activity is using the layout version with + // the fragment_container FrameLayout + if (findViewById(R.id.api_select_pub_keys_fragment_container) != null) { + + // However, if we're being restored from a previous state, + // then we don't need to do anything and should return or else + // we could end up with overlapping fragments. + if (savedInstanceState != null) { + return; + } + + // Create an instance of the fragment + mSelectFragment = SelectPublicKeyFragment.newInstance(selectedMasterKeyIds); + + // Add the fragment to the 'fragment_container' FrameLayout + getSupportFragmentManager().beginTransaction() + .add(R.id.api_select_pub_keys_fragment_container, mSelectFragment).commit(); + } + } else if (ACTION_ERROR_MESSAGE.equals(action)) { + String errorMessage = intent.getStringExtra(EXTRA_ERROR_MESSAGE); + + String text = "" + errorMessage + ""; + + // Inflate a "Done" custom action bar view + ActionBarHelper.setOneButtonView(getSupportActionBar(), + R.string.btn_okay, R.drawable.ic_action_done, + new View.OnClickListener() { + + @Override + public void onClick(View v) { + RemoteServiceActivity.this.setResult(RESULT_CANCELED); + RemoteServiceActivity.this.finish(); + } + }); + + setContentView(R.layout.api_app_error_message); + + // set text on view + HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_app_error_message_text); + textView.setHtmlFromString(text); + } else { + Log.e(Constants.TAG, "Action does not exist!"); + setResult(RESULT_CANCELED); + finish(); + } + } + + /** + * Shows passphrase dialog to cache a new passphrase the user enters for using it later for + * encryption. Based on mSecretKeyId it asks for a passphrase to open a private key or it asks + * for a symmetric passphrase + */ + private void showPassphraseDialog(final Intent data, long secretKeyId) { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + // return given params again, for calling the service method again + RemoteServiceActivity.this.setResult(RESULT_OK, data); + } else { + RemoteServiceActivity.this.setResult(RESULT_CANCELED); + } + + RemoteServiceActivity.this.finish(); + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + try { + PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(this, + messenger, secretKeyId); + + passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); + } catch (PgpGeneralException e) { + Log.d(Constants.TAG, "No passphrase for this secret key, do pgp operation directly!"); + // return given params again, for calling the service method again + setResult(RESULT_OK, data); + finish(); + } + } +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettings.java deleted file mode 100644 index 6f2d67efb..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettings.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.service.remote; - -import org.spongycastle.bcpg.HashAlgorithmTags; -import org.spongycastle.openpgp.PGPEncryptedData; -import org.sufficientlysecure.keychain.Id; - -public class AppSettings { - private String mPackageName; - private byte[] mPackageSignature; - private long mKeyId = Id.key.none; - private int mEncryptionAlgorithm; - private int mHashAlgorithm; - private int mCompression; - - public AppSettings() { - - } - - public AppSettings(String packageName, byte[] packageSignature) { - super(); - this.mPackageName = packageName; - this.mPackageSignature = packageSignature; - // defaults: - this.mEncryptionAlgorithm = PGPEncryptedData.AES_256; - this.mHashAlgorithm = HashAlgorithmTags.SHA512; - this.mCompression = Id.choice.compression.zlib; - } - - public String getPackageName() { - return mPackageName; - } - - public void setPackageName(String packageName) { - this.mPackageName = packageName; - } - - public byte[] getPackageSignature() { - return mPackageSignature; - } - - public void setPackageSignature(byte[] packageSignature) { - this.mPackageSignature = packageSignature; - } - - public long getKeyId() { - return mKeyId; - } - - public void setKeyId(long scretKeyId) { - this.mKeyId = scretKeyId; - } - - public int getEncryptionAlgorithm() { - return mEncryptionAlgorithm; - } - - public void setEncryptionAlgorithm(int encryptionAlgorithm) { - this.mEncryptionAlgorithm = encryptionAlgorithm; - } - - public int getHashAlgorithm() { - return mHashAlgorithm; - } - - public void setHashAlgorithm(int hashAlgorithm) { - this.mHashAlgorithm = hashAlgorithm; - } - - public int getCompression() { - return mCompression; - } - - public void setCompression(int compression) { - this.mCompression = compression; - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java deleted file mode 100644 index 2ef170dec..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.service.remote; - -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.support.v7.app.ActionBarActivity; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.ActionBarHelper; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.util.Log; - -public class AppSettingsActivity extends ActionBarActivity { - private Uri mAppUri; - - private AppSettingsFragment mSettingsFragment; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Inflate a "Done" custom action bar - ActionBarHelper.setOneButtonView(getSupportActionBar(), - R.string.api_settings_save, R.drawable.ic_action_done, - new View.OnClickListener() { - @Override - public void onClick(View v) { - // "Done" - save(); - } - }); - - setContentView(R.layout.api_app_settings_activity); - - mSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( - R.id.api_app_settings_fragment); - - Intent intent = getIntent(); - mAppUri = intent.getData(); - if (mAppUri == null) { - Log.e(Constants.TAG, "Intent data missing. Should be Uri of app!"); - finish(); - return; - } else { - Log.d(Constants.TAG, "uri: " + mAppUri); - loadData(mAppUri); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - getMenuInflater().inflate(R.menu.api_app_settings, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.menu_api_settings_revoke: - revokeAccess(); - return true; - case R.id.menu_api_settings_cancel: - finish(); - return true; - } - return super.onOptionsItemSelected(item); - } - - private void loadData(Uri appUri) { - AppSettings settings = ProviderHelper.getApiAppSettings(this, appUri); - mSettingsFragment.setAppSettings(settings); - } - - private void revokeAccess() { - if (getContentResolver().delete(mAppUri, null, null) <= 0) { - throw new RuntimeException(); - } - finish(); - } - - private void save() { - ProviderHelper.updateApiApp(this, mSettingsFragment.getAppSettings(), mAppUri); - - finish(); - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java deleted file mode 100644 index 52b06a2ae..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2013-2014 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.service.remote; - -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemSelectedListener; -import android.widget.ImageView; -import android.widget.Spinner; -import android.widget.TextView; - -import org.spongycastle.util.encoders.Hex; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; -import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter; -import org.sufficientlysecure.keychain.util.AlgorithmNames; -import org.sufficientlysecure.keychain.util.Log; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -public class AppSettingsFragment extends Fragment implements - SelectSecretKeyLayoutFragment.SelectSecretKeyCallback { - - // model - private AppSettings mAppSettings; - - // view - private TextView mAppNameView; - private ImageView mAppIconView; - private Spinner mEncryptionAlgorithm; - private Spinner mHashAlgorithm; - private Spinner mCompression; - private TextView mPackageName; - private TextView mPackageSignature; - - private SelectSecretKeyLayoutFragment mSelectKeyFragment; - - KeyValueSpinnerAdapter mEncryptionAdapter; - KeyValueSpinnerAdapter mHashAdapter; - KeyValueSpinnerAdapter mCompressionAdapter; - - public AppSettings getAppSettings() { - return mAppSettings; - } - - public void setAppSettings(AppSettings appSettings) { - this.mAppSettings = appSettings; - setPackage(appSettings.getPackageName()); - mPackageName.setText(appSettings.getPackageName()); - - try { - MessageDigest md = MessageDigest.getInstance("SHA-256"); - md.update(appSettings.getPackageSignature()); - byte[] digest = md.digest(); - String signature = new String(Hex.encode(digest)); - - mPackageSignature.setText(signature); - } catch (NoSuchAlgorithmException e) { - Log.e(Constants.TAG, "Should not happen!", e); - } - - mSelectKeyFragment.selectKey(appSettings.getKeyId()); - mEncryptionAlgorithm.setSelection(mEncryptionAdapter.getPosition(appSettings - .getEncryptionAlgorithm())); - mHashAlgorithm.setSelection(mHashAdapter.getPosition(appSettings.getHashAlgorithm())); - mCompression.setSelection(mCompressionAdapter.getPosition(appSettings.getCompression())); - } - - /** - * Inflate the layout for this fragment - */ - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.api_app_settings_fragment, container, false); - initView(view); - return view; - } - - /** - * Set error String on key selection - * - * @param error - */ - public void setErrorOnSelectKeyFragment(String error) { - mSelectKeyFragment.setError(error); - } - - private void initView(View view) { - mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getFragmentManager().findFragmentById( - R.id.api_app_settings_select_key_fragment); - mSelectKeyFragment.setCallback(this); - - mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name); - mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon); - mEncryptionAlgorithm = (Spinner) view - .findViewById(R.id.api_app_settings_encryption_algorithm); - mHashAlgorithm = (Spinner) view.findViewById(R.id.api_app_settings_hash_algorithm); - mCompression = (Spinner) view.findViewById(R.id.api_app_settings_compression); - mPackageName = (TextView) view.findViewById(R.id.api_app_settings_package_name); - mPackageSignature = (TextView) view.findViewById(R.id.api_app_settings_package_signature); - - AlgorithmNames algorithmNames = new AlgorithmNames(getActivity()); - - mEncryptionAdapter = new KeyValueSpinnerAdapter(getActivity(), - algorithmNames.getEncryptionNames()); - mEncryptionAlgorithm.setAdapter(mEncryptionAdapter); - mEncryptionAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() { - - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - mAppSettings.setEncryptionAlgorithm((int) id); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - - mHashAdapter = new KeyValueSpinnerAdapter(getActivity(), algorithmNames.getHashNames()); - mHashAlgorithm.setAdapter(mHashAdapter); - mHashAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() { - - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - mAppSettings.setHashAlgorithm((int) id); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - - mCompressionAdapter = new KeyValueSpinnerAdapter(getActivity(), - algorithmNames.getCompressionNames()); - mCompression.setAdapter(mCompressionAdapter); - mCompression.setOnItemSelectedListener(new OnItemSelectedListener() { - - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - mAppSettings.setCompression((int) id); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - } - - private void setPackage(String packageName) { - PackageManager pm = getActivity().getApplicationContext().getPackageManager(); - - // get application name and icon from package manager - String appName = null; - Drawable appIcon = null; - try { - ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); - - appName = (String) pm.getApplicationLabel(ai); - appIcon = pm.getApplicationIcon(ai); - } catch (final NameNotFoundException e) { - // fallback - appName = packageName; - } - mAppNameView.setText(appName); - mAppIconView.setImageDrawable(appIcon); - } - - /** - * callback from select secret key fragment - */ - @Override - public void onKeySelected(long secretKeyId) { - mAppSettings.setKeyId(secretKeyId); - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java deleted file mode 100644 index 95dc897f0..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright (C) 2013-2014 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.service.remote; - -import android.app.PendingIntent; -import android.content.Intent; -import android.database.Cursor; -import android.net.Uri; -import android.os.IBinder; -import android.os.ParcelFileDescriptor; -import org.openintents.openpgp.IOpenPgpService; -import org.openintents.openpgp.OpenPgpError; -import org.openintents.openpgp.OpenPgpSignatureResult; -import org.openintents.openpgp.util.OpenPgpApi; -import org.spongycastle.util.Arrays; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.Id; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; -import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.PassphraseCacheService; -import org.sufficientlysecure.keychain.util.InputData; -import org.sufficientlysecure.keychain.util.Log; - -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; - -public class OpenPgpService extends RemoteService { - - private static final int PRIVATE_REQUEST_CODE_PASSPHRASE = 551; - private static final int PRIVATE_REQUEST_CODE_USER_IDS = 552; - private static final int PRIVATE_REQUEST_CODE_GET_KEYS = 553; - - /** - * Search database for key ids based on emails. - * - * @param encryptionUserIds - * @return - */ - private Intent getKeyIdsFromEmails(Intent data, String[] encryptionUserIds) { - // find key ids to given emails in database - ArrayList keyIds = new ArrayList(); - - boolean missingUserIdsCheck = false; - boolean dublicateUserIdsCheck = false; - ArrayList missingUserIds = new ArrayList(); - ArrayList dublicateUserIds = new ArrayList(); - - for (String email : encryptionUserIds) { - Uri uri = KeychainContract.KeyRings.buildPublicKeyRingsByEmailsUri(email); - Cursor cur = getContentResolver().query(uri, null, null, null, null); - if (cur.moveToFirst()) { - long id = cur.getLong(cur.getColumnIndex(KeychainContract.KeyRings.MASTER_KEY_ID)); - keyIds.add(id); - } else { - missingUserIdsCheck = true; - missingUserIds.add(email); - Log.d(Constants.TAG, "user id missing"); - } - if (cur.moveToNext()) { - dublicateUserIdsCheck = true; - dublicateUserIds.add(email); - Log.d(Constants.TAG, "more than one user id with the same email"); - } - } - - // convert to long[] - long[] keyIdsArray = new long[keyIds.size()]; - for (int i = 0; i < keyIdsArray.length; i++) { - keyIdsArray[i] = keyIds.get(i); - } - - // allow the user to verify pub key selection - if (missingUserIdsCheck || dublicateUserIdsCheck) { - // build PendingIntent - Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); - intent.setAction(RemoteServiceActivity.ACTION_SELECT_PUB_KEYS); - intent.putExtra(RemoteServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray); - intent.putExtra(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds); - intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, dublicateUserIds); - intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - - PendingIntent pi = PendingIntent.getActivity - (getBaseContext(), PRIVATE_REQUEST_CODE_USER_IDS, intent, 0); - - // return PendingIntent to be executed by client - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_INTENT, pi); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); - return result; - } - - if (keyIdsArray.length == 0) { - return null; - } - - Intent result = new Intent(); - result.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keyIdsArray); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); - return result; - } - - private Intent getPassphraseBundleIntent(Intent data, long keyId) { - // build PendingIntent for passphrase input - Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); - intent.setAction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE); - intent.putExtra(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, keyId); - // pass params through to activity that it can be returned again later to repeat pgp operation - intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - PendingIntent pi = PendingIntent.getActivity - (getBaseContext(), PRIVATE_REQUEST_CODE_PASSPHRASE, intent, 0); - - // return PendingIntent to be executed by client - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_INTENT, pi); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); - return result; - } - - private Intent signImpl(Intent data, ParcelFileDescriptor input, - ParcelFileDescriptor output, AppSettings appSettings) { - try { - boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); - - // get passphrase from cache, if key has "no" passphrase, this returns an empty String - String passphrase; - if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) { - passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE); - } else { - passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); - } - if (passphrase == null) { - // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId()); - return passphraseBundle; - } - - // Get Input- and OutputStream from ParcelFileDescriptor - InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); - OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output); - try { - long inputLength = is.available(); - InputData inputData = new InputData(is, inputLength); - - // sign-only - PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os); - builder.enableAsciiArmorOutput(asciiArmor) - .signatureHashAlgorithm(appSettings.getHashAlgorithm()) - .signatureForceV3(false) - .signatureKeyId(appSettings.getKeyId()) - .signaturePassphrase(passphrase); - builder.build().execute(); - } finally { - is.close(); - os.close(); - } - - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); - return result; - } catch (Exception e) { - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_ERROR, - new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); - return result; - } - } - - private Intent encryptAndSignImpl(Intent data, ParcelFileDescriptor input, - ParcelFileDescriptor output, AppSettings appSettings, boolean sign) { - try { - boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); - - long[] keyIds; - if (data.hasExtra(OpenPgpApi.EXTRA_KEY_IDS)) { - keyIds = data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS); - } else if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS)) { - // get key ids based on given user ids - String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS); - // give params through to activity... - Intent result = getKeyIdsFromEmails(data, userIds); - - if (result.getIntExtra(OpenPgpApi.RESULT_CODE, 0) == OpenPgpApi.RESULT_CODE_SUCCESS) { - keyIds = result.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS); - } else { - // if not success -> result contains a PendingIntent for user interaction - return result; - } - } else { - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_ERROR, - new OpenPgpError(OpenPgpError.GENERIC_ERROR, - "Missing parameter user_ids or key_ids!")); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); - return result; - } - - // add own key for encryption - keyIds = Arrays.copyOf(keyIds, keyIds.length + 1); - keyIds[keyIds.length - 1] = appSettings.getKeyId(); - - // build InputData and write into OutputStream - // Get Input- and OutputStream from ParcelFileDescriptor - InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); - OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output); - try { - long inputLength = is.available(); - InputData inputData = new InputData(is, inputLength); - - PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os); - builder.enableAsciiArmorOutput(asciiArmor) - .compressionId(appSettings.getCompression()) - .symmetricEncryptionAlgorithm(appSettings.getEncryptionAlgorithm()) - .encryptionKeyIds(keyIds); - - if (sign) { - String passphrase; - if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) { - passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE); - } else { - passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), - appSettings.getKeyId()); - } - if (passphrase == null) { - // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId()); - return passphraseBundle; - } - - // sign and encrypt - builder.signatureHashAlgorithm(appSettings.getHashAlgorithm()) - .signatureForceV3(false) - .signatureKeyId(appSettings.getKeyId()) - .signaturePassphrase(passphrase); - } else { - // encrypt only - builder.signatureKeyId(Id.key.none); - } - // execute PGP operation! - builder.build().execute(); - } finally { - is.close(); - os.close(); - } - - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); - return result; - } catch (Exception e) { - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_ERROR, - new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); - return result; - } - } - - private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input, - ParcelFileDescriptor output, AppSettings appSettings) { - try { - // Get Input- and OutputStream from ParcelFileDescriptor - InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); - OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output); - - Intent result = new Intent(); - try { - - String passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE); - long inputLength = is.available(); - InputData inputData = new InputData(is, inputLength); - - PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os); - builder.assumeSymmetric(false) // no support for symmetric encryption - // allow only the private key for this app for decryption - .enforcedKeyId(appSettings.getKeyId()) - .passphrase(passphrase); - - // TODO: currently does not support binary signed-only content - PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute(); - - if (decryptVerifyResult.isKeyPassphraseNeeded()) { - // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId()); - return passphraseBundle; - } else if (decryptVerifyResult.isSymmetricPassphraseNeeded()) { - throw new PgpGeneralException("Decryption of symmetric content not supported by API!"); - } - - OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); - if (signatureResult != null) { - if (signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY) { - // If signature is unknown we return an _additional_ PendingIntent - // to retrieve the missing key - // TODO!!! - Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); - intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE); - intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo"); - intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - - PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_GET_KEYS, intent, 0); - - result.putExtra(OpenPgpApi.RESULT_INTENT, pi); - } - - result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult); - } - - } finally { - is.close(); - os.close(); - } - - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); - return result; - } catch (Exception e) { - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_ERROR, - new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); - return result; - } - } - - private Intent getKeyImpl(Intent data) { - try { - long keyId = data.getLongExtra(OpenPgpApi.EXTRA_KEY_ID, 0); - - if (ProviderHelper.getPGPPublicKeyByKeyId(this, keyId) == null) { - Intent result = new Intent(); - - // If keys are not in db we return an additional PendingIntent - // to retrieve the missing key - // TODO!!! - Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); - intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE); - intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo"); - intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - - PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_GET_KEYS, intent, 0); - - result.putExtra(OpenPgpApi.RESULT_INTENT, pi); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); - return result; - } else { - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); - return result; - } - } catch (Exception e) { - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_ERROR, - new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); - return result; - } - } - - private Intent getKeyIdsImpl(Intent data) { - // get key ids based on given user ids - String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS); - Intent result = getKeyIdsFromEmails(data, userIds); - return result; - } - - /** - * Check requirements: - * - params != null - * - has supported API version - * - is allowed to call the service (access has been granted) - * - * @param data - * @return null if everything is okay, or a Bundle with an error/PendingIntent - */ - private Intent checkRequirements(Intent data) { - // params Bundle is required! - if (data == null) { - Intent result = new Intent(); - OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!"); - result.putExtra(OpenPgpApi.RESULT_ERROR, error); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); - return result; - } - - // version code is required and needs to correspond to version code of service! - if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != OpenPgpApi.API_VERSION) { - Intent result = new Intent(); - OpenPgpError error = new OpenPgpError - (OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!"); - result.putExtra(OpenPgpApi.RESULT_ERROR, error); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); - return result; - } - - // check if caller is allowed to access openpgp keychain - Intent result = isAllowed(data); - if (result != null) { - return result; - } - - return null; - } - - // TODO: multi-threading - private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() { - - @Override - public Intent execute(Intent data, ParcelFileDescriptor input, ParcelFileDescriptor output) { - Intent errorResult = checkRequirements(data); - if (errorResult != null) { - return errorResult; - } - - final AppSettings appSettings = getAppSettings(); - - String action = data.getAction(); - if (OpenPgpApi.ACTION_SIGN.equals(action)) { - return signImpl(data, input, output, appSettings); - } else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) { - return encryptAndSignImpl(data, input, output, appSettings, false); - } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) { - return encryptAndSignImpl(data, input, output, appSettings, true); - } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) { - return decryptAndVerifyImpl(data, input, output, appSettings); - } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) { - return getKeyImpl(data); - } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) { - return getKeyIdsImpl(data); - } else { - return null; - } - } - - }; - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsAdapter.java deleted file mode 100644 index e0dc4162f..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsAdapter.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.service.remote; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.database.Cursor; -import android.support.v4.widget.CursorAdapter; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; - -public class RegisteredAppsAdapter extends CursorAdapter { - - private LayoutInflater mInflater; - private PackageManager mPM; - - public RegisteredAppsAdapter(Context context, Cursor c, int flags) { - super(context, c, flags); - - mInflater = LayoutInflater.from(context); - mPM = context.getApplicationContext().getPackageManager(); - } - - @Override - public void bindView(View view, Context context, Cursor cursor) { - TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name); - ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon); - - String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME)); - if (packageName != null) { - // get application name - try { - ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0); - - text.setText(mPM.getApplicationLabel(ai)); - icon.setImageDrawable(mPM.getApplicationIcon(ai)); - } catch (final NameNotFoundException e) { - // fallback - text.setText(packageName); - } - } else { - // fallback - text.setText(packageName); - } - - } - - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - return mInflater.inflate(R.layout.api_apps_adapter_list_item, null); - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListActivity.java deleted file mode 100644 index f6f216efd..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListActivity.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.service.remote; - -import android.os.Bundle; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.ui.DrawerActivity; - -public class RegisteredAppsListActivity extends DrawerActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.api_apps_list_activity); - - setupDrawerNavigation(savedInstanceState); - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListFragment.java deleted file mode 100644 index 25d0c7593..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListFragment.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.service.remote; - -import android.content.ContentUris; -import android.content.Intent; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.support.v4.app.ListFragment; -import android.support.v4.app.LoaderManager; -import android.support.v4.content.CursorLoader; -import android.support.v4.content.Loader; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; - -public class RegisteredAppsListFragment extends ListFragment implements - LoaderManager.LoaderCallbacks { - - // This is the Adapter being used to display the list's data. - RegisteredAppsAdapter mAdapter; - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - getListView().setOnItemClickListener(new OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int position, long id) { - // edit app settings - Intent intent = new Intent(getActivity(), AppSettingsActivity.class); - intent.setData(ContentUris.withAppendedId(KeychainContract.ApiApps.CONTENT_URI, id)); - startActivity(intent); - } - }); - - // Give some text to display if there is no data. In a real - // application this would come from a resource. - setEmptyText(getString(R.string.api_no_apps)); - - // We have a menu item to show in action bar. - setHasOptionsMenu(true); - - // Create an empty adapter we will use to display the loaded data. - mAdapter = new RegisteredAppsAdapter(getActivity(), null, 0); - setListAdapter(mAdapter); - - // Prepare the loader. Either re-connect with an existing one, - // or start a new one. - getLoaderManager().initLoader(0, null, this); - } - - // These are the Contacts rows that we will retrieve. - static final String[] PROJECTION = new String[]{ApiApps._ID, ApiApps.PACKAGE_NAME}; - - public Loader onCreateLoader(int id, Bundle args) { - // This is called when a new Loader needs to be created. This - // sample only has one Loader, so we don't care about the ID. - // First, pick the base URI to use depending on whether we are - // currently filtering. - Uri baseUri = ApiApps.CONTENT_URI; - - // Now create and return a CursorLoader that will take care of - // creating a Cursor for the data being displayed. - return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null, - ApiApps.PACKAGE_NAME + " COLLATE LOCALIZED ASC"); - } - - public void onLoadFinished(Loader loader, Cursor data) { - // Swap the new cursor in. (The framework will take care of closing the - // old cursor once we return.) - mAdapter.swapCursor(data); - } - - public void onLoaderReset(Loader loader) { - // This is called when the last Cursor provided to onLoadFinished() - // above is about to be closed. We need to make sure we are no - // longer using it. - mAdapter.swapCursor(null); - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java deleted file mode 100644 index 6a883316a..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2013-2014 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.service.remote; - -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.Signature; -import android.net.Uri; -import android.os.Binder; -import org.openintents.openpgp.OpenPgpError; -import org.openintents.openpgp.util.OpenPgpApi; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.util.Log; - -import java.util.ArrayList; -import java.util.Arrays; - -/** - * Abstract service class for remote APIs that handle app registration and user input. - */ -public abstract class RemoteService extends Service { - Context mContext; - - private static final int PRIVATE_REQUEST_CODE_REGISTER = 651; - private static final int PRIVATE_REQUEST_CODE_ERROR = 652; - - - public Context getContext() { - return mContext; - } - - protected Intent isAllowed(Intent data) { - try { - if (isCallerAllowed(false)) { - - return null; - } else { - String[] callingPackages = getPackageManager().getPackagesForUid( - Binder.getCallingUid()); - // TODO: currently simply uses first entry - String packageName = callingPackages[0]; - - byte[] packageSignature; - try { - packageSignature = getPackageSignature(packageName); - } catch (NameNotFoundException e) { - Log.e(Constants.TAG, "Should not happen, returning!", e); - // return error - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); - result.putExtra(OpenPgpApi.RESULT_ERROR, - new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); - return result; - } - Log.e(Constants.TAG, "Not allowed to use service! return PendingIntent for registration!"); - - Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); - intent.setAction(RemoteServiceActivity.ACTION_REGISTER); - intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName); - intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature); - intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - - PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_REGISTER, intent, 0); - - // return PendingIntent to be executed by client - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); - result.putExtra(OpenPgpApi.RESULT_INTENT, pi); - - return result; - } - } catch (WrongPackageSignatureException e) { - Log.e(Constants.TAG, "wrong signature!", e); - - Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); - intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE); - intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, - getString(R.string.api_error_wrong_signature)); - intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - - PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_ERROR, intent, 0); - - // return PendingIntent to be executed by client - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); - result.putExtra(OpenPgpApi.RESULT_INTENT, pi); - - return result; - } - } - - private byte[] getPackageSignature(String packageName) throws NameNotFoundException { - PackageInfo pkgInfo = getPackageManager().getPackageInfo(packageName, - PackageManager.GET_SIGNATURES); - Signature[] signatures = pkgInfo.signatures; - // TODO: Only first signature?! - byte[] packageSignature = signatures[0].toByteArray(); - - return packageSignature; - } - - /** - * Retrieves AppSettings from database for the application calling this remote service - * - * @return - */ - protected AppSettings getAppSettings() { - String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid()); - - // get app settings for this package - for (int i = 0; i < callingPackages.length; i++) { - String currentPkg = callingPackages[i]; - - Uri uri = KeychainContract.ApiApps.buildByPackageNameUri(currentPkg); - - AppSettings settings = ProviderHelper.getApiAppSettings(this, uri); - - if (settings != null) { - return settings; - } - } - - return null; - } - - /** - * Checks if process that binds to this service (i.e. the package name corresponding to the - * process) is in the list of allowed package names. - * - * @param allowOnlySelf allow only Keychain app itself - * @return true if process is allowed to use this service - * @throws WrongPackageSignatureException - */ - private boolean isCallerAllowed(boolean allowOnlySelf) throws WrongPackageSignatureException { - return isUidAllowed(Binder.getCallingUid(), allowOnlySelf); - } - - private boolean isUidAllowed(int uid, boolean allowOnlySelf) - throws WrongPackageSignatureException { - if (android.os.Process.myUid() == uid) { - return true; - } - if (allowOnlySelf) { // barrier - return false; - } - - String[] callingPackages = getPackageManager().getPackagesForUid(uid); - - // is calling package allowed to use this service? - for (int i = 0; i < callingPackages.length; i++) { - String currentPkg = callingPackages[i]; - - if (isPackageAllowed(currentPkg)) { - return true; - } - } - - Log.d(Constants.TAG, "Caller is NOT allowed!"); - return false; - } - - /** - * Checks if packageName is a registered app for the API. Does not return true for own package! - * - * @param packageName - * @return - * @throws WrongPackageSignatureException - */ - private boolean isPackageAllowed(String packageName) throws WrongPackageSignatureException { - Log.d(Constants.TAG, "packageName: " + packageName); - - ArrayList allowedPkgs = ProviderHelper.getRegisteredApiApps(this); - Log.d(Constants.TAG, "allowed: " + allowedPkgs); - - // check if package is allowed to use our service - if (allowedPkgs.contains(packageName)) { - Log.d(Constants.TAG, "Package is allowed! packageName: " + packageName); - - // check package signature - byte[] currentSig; - try { - currentSig = getPackageSignature(packageName); - } catch (NameNotFoundException e) { - throw new WrongPackageSignatureException(e.getMessage()); - } - - byte[] storedSig = ProviderHelper.getApiAppSignature(this, packageName); - if (Arrays.equals(currentSig, storedSig)) { - Log.d(Constants.TAG, - "Package signature is correct! (equals signature from database)"); - return true; - } else { - throw new WrongPackageSignatureException( - "PACKAGE NOT ALLOWED! Signature wrong! (Signature not equals signature from database)"); - } - } - - return false; - } - - @Override - public void onCreate() { - super.onCreate(); - mContext = this; - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java deleted file mode 100644 index e20114853..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2013-2014 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.service.remote; - -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.Messenger; -import android.support.v7.app.ActionBarActivity; -import android.view.View; -import org.openintents.openpgp.util.OpenPgpApi; -import org.sufficientlysecure.htmltextview.HtmlTextView; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.Id; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.ActionBarHelper; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment; -import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; -import org.sufficientlysecure.keychain.util.Log; - -import java.util.ArrayList; - -public class RemoteServiceActivity extends ActionBarActivity { - - public static final String ACTION_REGISTER = Constants.INTENT_PREFIX + "API_ACTIVITY_REGISTER"; - public static final String ACTION_CACHE_PASSPHRASE = Constants.INTENT_PREFIX - + "API_ACTIVITY_CACHE_PASSPHRASE"; - public static final String ACTION_SELECT_PUB_KEYS = Constants.INTENT_PREFIX - + "API_ACTIVITY_SELECT_PUB_KEYS"; - public static final String ACTION_ERROR_MESSAGE = Constants.INTENT_PREFIX - + "API_ACTIVITY_ERROR_MESSAGE"; - - public static final String EXTRA_MESSENGER = "messenger"; - - public static final String EXTRA_DATA = "data"; - - // passphrase action - public static final String EXTRA_SECRET_KEY_ID = "secret_key_id"; - // register action - public static final String EXTRA_PACKAGE_NAME = "package_name"; - public static final String EXTRA_PACKAGE_SIGNATURE = "package_signature"; - // select pub keys action - public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "master_key_ids"; - public static final String EXTRA_MISSING_USER_IDS = "missing_user_ids"; - public static final String EXTRA_DUBLICATE_USER_IDS = "dublicate_user_ids"; - // error message - public static final String EXTRA_ERROR_MESSAGE = "error_message"; - - // register view - private AppSettingsFragment mSettingsFragment; - // select pub keys view - private SelectPublicKeyFragment mSelectFragment; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - handleActions(getIntent(), savedInstanceState); - } - - protected void handleActions(Intent intent, Bundle savedInstanceState) { - - String action = intent.getAction(); - final Bundle extras = intent.getExtras(); - - - if (ACTION_REGISTER.equals(action)) { - final String packageName = extras.getString(EXTRA_PACKAGE_NAME); - final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE); - - // Inflate a "Done"/"Cancel" custom action bar view - ActionBarHelper.setTwoButtonView(getSupportActionBar(), - R.string.api_register_allow, R.drawable.ic_action_done, - new View.OnClickListener() { - @Override - public void onClick(View v) { - // Allow - - // user needs to select a key! - if (mSettingsFragment.getAppSettings().getKeyId() == Id.key.none) { - mSettingsFragment.setErrorOnSelectKeyFragment( - getString(R.string.api_register_error_select_key)); - } else { - ProviderHelper.insertApiApp(RemoteServiceActivity.this, - mSettingsFragment.getAppSettings()); - - // give data through for new service call - Intent resultData = extras.getParcelable(EXTRA_DATA); - RemoteServiceActivity.this.setResult(RESULT_OK, resultData); - RemoteServiceActivity.this.finish(); - } - } - }, R.string.api_register_disallow, R.drawable.ic_action_cancel, - new View.OnClickListener() { - @Override - public void onClick(View v) { - // Disallow - RemoteServiceActivity.this.setResult(RESULT_CANCELED); - RemoteServiceActivity.this.finish(); - } - } - ); - - setContentView(R.layout.api_app_register_activity); - - mSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( - R.id.api_app_settings_fragment); - - AppSettings settings = new AppSettings(packageName, packageSignature); - mSettingsFragment.setAppSettings(settings); - } else if (ACTION_CACHE_PASSPHRASE.equals(action)) { - long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID); - Intent resultData = extras.getParcelable(EXTRA_DATA); - - showPassphraseDialog(resultData, secretKeyId); - } else if (ACTION_SELECT_PUB_KEYS.equals(action)) { - long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS); - ArrayList missingUserIds = intent - .getStringArrayListExtra(EXTRA_MISSING_USER_IDS); - ArrayList dublicateUserIds = intent - .getStringArrayListExtra(EXTRA_DUBLICATE_USER_IDS); - - // TODO: do this with spannable instead of HTML to prevent parsing failures with weird user ids - String text = "" + getString(R.string.api_select_pub_keys_text) + ""; - text += "

"; - if (missingUserIds != null && missingUserIds.size() > 0) { - text += getString(R.string.api_select_pub_keys_missing_text); - text += "
"; - text += "
    "; - for (String userId : missingUserIds) { - text += "
  • " + userId + "
  • "; - } - text += "
"; - text += "
"; - } - if (dublicateUserIds != null && dublicateUserIds.size() > 0) { - text += getString(R.string.api_select_pub_keys_dublicates_text); - text += "
"; - text += "
    "; - for (String userId : dublicateUserIds) { - text += "
  • " + userId + "
  • "; - } - text += "
"; - } - - // Inflate a "Done"/"Cancel" custom action bar view - ActionBarHelper.setTwoButtonView(getSupportActionBar(), - R.string.btn_okay, R.drawable.ic_action_done, - new View.OnClickListener() { - @Override - public void onClick(View v) { - // add key ids to params Bundle for new request - Intent resultData = extras.getParcelable(EXTRA_DATA); - resultData.putExtra(OpenPgpApi.EXTRA_KEY_IDS, - mSelectFragment.getSelectedMasterKeyIds()); - - RemoteServiceActivity.this.setResult(RESULT_OK, resultData); - RemoteServiceActivity.this.finish(); - } - }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() { - @Override - public void onClick(View v) { - // cancel - RemoteServiceActivity.this.setResult(RESULT_CANCELED); - RemoteServiceActivity.this.finish(); - } - } - ); - - setContentView(R.layout.api_app_select_pub_keys_activity); - - // set text on view - HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_select_pub_keys_text); - textView.setHtmlFromString(text); - - /* Load select pub keys fragment */ - // Check that the activity is using the layout version with - // the fragment_container FrameLayout - if (findViewById(R.id.api_select_pub_keys_fragment_container) != null) { - - // However, if we're being restored from a previous state, - // then we don't need to do anything and should return or else - // we could end up with overlapping fragments. - if (savedInstanceState != null) { - return; - } - - // Create an instance of the fragment - mSelectFragment = SelectPublicKeyFragment.newInstance(selectedMasterKeyIds); - - // Add the fragment to the 'fragment_container' FrameLayout - getSupportFragmentManager().beginTransaction() - .add(R.id.api_select_pub_keys_fragment_container, mSelectFragment).commit(); - } - } else if (ACTION_ERROR_MESSAGE.equals(action)) { - String errorMessage = intent.getStringExtra(EXTRA_ERROR_MESSAGE); - - String text = "" + errorMessage + ""; - - // Inflate a "Done" custom action bar view - ActionBarHelper.setOneButtonView(getSupportActionBar(), - R.string.btn_okay, R.drawable.ic_action_done, - new View.OnClickListener() { - - @Override - public void onClick(View v) { - RemoteServiceActivity.this.setResult(RESULT_CANCELED); - RemoteServiceActivity.this.finish(); - } - }); - - setContentView(R.layout.api_app_error_message); - - // set text on view - HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_app_error_message_text); - textView.setHtmlFromString(text); - } else { - Log.e(Constants.TAG, "Action does not exist!"); - setResult(RESULT_CANCELED); - finish(); - } - } - - /** - * Shows passphrase dialog to cache a new passphrase the user enters for using it later for - * encryption. Based on mSecretKeyId it asks for a passphrase to open a private key or it asks - * for a symmetric passphrase - */ - private void showPassphraseDialog(final Intent data, long secretKeyId) { - // Message is received after passphrase is cached - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - // return given params again, for calling the service method again - RemoteServiceActivity.this.setResult(RESULT_OK, data); - } else { - RemoteServiceActivity.this.setResult(RESULT_CANCELED); - } - - RemoteServiceActivity.this.finish(); - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - try { - PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(this, - messenger, secretKeyId); - - passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); - } catch (PgpGeneralException e) { - Log.d(Constants.TAG, "No passphrase for this secret key, do pgp operation directly!"); - // return given params again, for calling the service method again - setResult(RESULT_OK, data); - finish(); - } - } -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java deleted file mode 100644 index 0b642086a..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.service.remote; - -public class WrongPackageSignatureException extends Exception { - - private static final long serialVersionUID = -8294642703122196028L; - - public WrongPackageSignatureException(String message) { - super(message); - } -} -- cgit v1.2.3 From f082b53118e7a174b8c9a79964abaeef4a34fa29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 23 Mar 2014 02:17:39 +0100 Subject: Extend provider for new api tables --- .../keychain/provider/KeychainContract.java | 64 ++++++++- .../keychain/provider/KeychainDatabase.java | 8 +- .../keychain/provider/KeychainProvider.java | 149 ++++++++++++++++++--- .../keychain/provider/ProviderHelper.java | 42 ++++-- 4 files changed, 222 insertions(+), 41 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index de51cebbb..aa4c1f131 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -63,7 +63,7 @@ public class KeychainContract { String ENCRYPTION_ALGORITHM = "encryption_algorithm"; String HASH_ALORITHM = "hash_algorithm"; String COMPRESSION = "compression"; - String PACKAGE_NAME = "package_name"; // foreign key to api_apps.package_name + String PACKAGE_NAME_FK = "package_name"; // foreign key to api_apps.package_name } public static final class KeyTypes { @@ -90,7 +90,10 @@ public class KeychainContract { public static final String PATH_USER_IDS = "user_ids"; public static final String PATH_KEYS = "keys"; - public static final String BASE_API_APPS = "api_apps"; + public static final String BASE_API = "api"; + public static final String PATH_APPS = "apps"; + public static final String PATH_ACCOUNTS = "accounts"; + public static final String PATH_BY_PACKAGE_NAME = "package_name"; public static class KeyRings implements KeyRingsColumns, BaseColumns { @@ -254,19 +257,70 @@ public class KeychainContract { } } + /** + * Join over ApiApps with ApiAppsAccounts + */ + public static class Api implements ApiAppsColumns, ApiAppsAccountsColumns, BaseColumns { + public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() + .appendPath(BASE_API).build(); + + /** + * Use if multiple items get returned + */ + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.apis"; + + /** + * Use if a single item is returned + */ + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api"; + + public static Uri buildIdUri(String rowId) { + return CONTENT_URI.buildUpon().appendPath(rowId).build(); + } + + public static Uri buildByPackageNameUri(String packageName) { + return CONTENT_URI.buildUpon().appendPath(PATH_BY_PACKAGE_NAME).appendPath(packageName) + .build(); + } + } + public static class ApiApps implements ApiAppsColumns, BaseColumns { public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() - .appendPath(BASE_API_APPS).build(); + .appendPath(BASE_API).appendPath(PATH_APPS).build(); + + /** + * Use if multiple items get returned + */ + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api.app"; + + /** + * Use if a single item is returned + */ + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api.apps"; + + public static Uri buildIdUri(String rowId) { + return CONTENT_URI.buildUpon().appendPath(rowId).build(); + } + + public static Uri buildByPackageNameUri(String packageName) { + return CONTENT_URI.buildUpon().appendPath(PATH_BY_PACKAGE_NAME).appendPath(packageName) + .build(); + } + } + + public static class ApiAccounts implements ApiAppsAccountsColumns, BaseColumns { + public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() + .appendPath(BASE_API).appendPath(PATH_ACCOUNTS).build(); /** * Use if multiple items get returned */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api_apps"; + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api.acoounts"; /** * Use if a single item is returned */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_apps"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api.account"; public static Uri buildIdUri(String rowId) { return CONTENT_URI.buildUpon().appendPath(rowId).build(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index f7c9fe79d..e56fa2f8f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -38,7 +38,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { String KEYS = "keys"; String USER_IDS = "user_ids"; String API_APPS = "api_apps"; - String API_APPS_ACCOUNTS = "api_apps_accounts"; + String API_ACCOUNTS = "api_accounts"; } private static final String CREATE_KEY_RINGS = "CREATE TABLE IF NOT EXISTS " + Tables.KEY_RINGS @@ -80,14 +80,14 @@ public class KeychainDatabase extends SQLiteOpenHelper { + ApiAppsColumns.PACKAGE_NAME + " TEXT UNIQUE, " + ApiAppsColumns.PACKAGE_SIGNATURE + " BLOB)"; - private static final String CREATE_API_APPS_ACCOUNTS = "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS_ACCOUNTS + private static final String CREATE_API_APPS_ACCOUNTS = "CREATE TABLE IF NOT EXISTS " + Tables.API_ACCOUNTS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + ApiAppsAccountsColumns.KEY_ID + " INT64, " + ApiAppsAccountsColumns.ENCRYPTION_ALGORITHM + " INTEGER, " + ApiAppsAccountsColumns.HASH_ALORITHM + " INTEGER, " + ApiAppsAccountsColumns.COMPRESSION + " INTEGER" - + ApiAppsAccountsColumns.PACKAGE_NAME + " TEXT NOT NULL, FOREIGN KEY(" - + ApiAppsAccountsColumns.PACKAGE_NAME + ") REFERENCES " + Tables.API_APPS + "(" + + ApiAppsAccountsColumns.PACKAGE_NAME_FK + " TEXT NOT NULL, FOREIGN KEY(" + + ApiAppsAccountsColumns.PACKAGE_NAME_FK + ") REFERENCES " + Tables.API_APPS + "(" + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE)"; KeychainDatabase(Context context) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 746449f7e..a094b13de 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Dominik Schürmann + * Copyright (C) 2012-2014 Dominik Schürmann * Copyright (C) 2010 Thialfihar * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,8 +28,19 @@ import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.provider.BaseColumns; import android.text.TextUtils; + import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.provider.KeychainContract.*; +import org.sufficientlysecure.keychain.provider.KeychainContract.Api; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyTypes; +import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns; +import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; +import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.util.Log; @@ -70,9 +81,15 @@ public class KeychainProvider extends ContentProvider { private static final int SECRET_KEY_RING_USER_ID = 221; private static final int SECRET_KEY_RING_USER_ID_BY_ROW_ID = 222; - private static final int API_APPS = 301; - private static final int API_APPS_BY_ROW_ID = 302; - private static final int API_APPS_BY_PACKAGE_NAME = 303; + private static final int API = 301; + private static final int API_BY_ROW_ID = 302; + private static final int API_BY_PACKAGE_NAME = 303; + private static final int API_APPS = 304; + private static final int API_APPS_BY_ROW_ID = 305; + private static final int API_APPS_BY_PACKAGE_NAME = 306; + private static final int API_ACCOUNTS = 307; + private static final int API_ACCOUNTS_BY_ROW_ID = 308; + private static final int API_ACCOUNTS_BY_PACKAGE_NAME = 309; private static final int UNIFIED_KEY_RING = 401; @@ -230,11 +247,27 @@ public class KeychainProvider extends ContentProvider { /** * API apps */ - matcher.addURI(authority, KeychainContract.BASE_API_APPS, API_APPS); - matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/#", API_APPS_BY_ROW_ID); - matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/" + matcher.addURI(authority, KeychainContract.BASE_API, API); + matcher.addURI(authority, KeychainContract.BASE_API + "/#", API_BY_ROW_ID); + matcher.addURI(authority, KeychainContract.BASE_API + "/" + + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_BY_PACKAGE_NAME); + + matcher.addURI(authority, KeychainContract.BASE_API + "/" + + KeychainContract.PATH_APPS, API_APPS); + matcher.addURI(authority, KeychainContract.BASE_API + "/" + + KeychainContract.PATH_APPS + "/#", API_APPS_BY_ROW_ID); + matcher.addURI(authority, KeychainContract.BASE_API + "/" + + KeychainContract.PATH_APPS + "/" + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_APPS_BY_PACKAGE_NAME); + matcher.addURI(authority, KeychainContract.BASE_API + "/" + + KeychainContract.PATH_ACCOUNTS, API_ACCOUNTS); + matcher.addURI(authority, KeychainContract.BASE_API + "/" + + KeychainContract.PATH_ACCOUNTS + "/#", API_ACCOUNTS_BY_ROW_ID); + matcher.addURI(authority, KeychainContract.BASE_API + "/" + + KeychainContract.PATH_ACCOUNTS + "/" + + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_ACCOUNTS_BY_PACKAGE_NAME); + /** * data stream * @@ -299,6 +332,13 @@ public class KeychainProvider extends ContentProvider { case SECRET_KEY_RING_USER_ID_BY_ROW_ID: return UserIds.CONTENT_ITEM_TYPE; + case API: + return Api.CONTENT_TYPE; + + case API_BY_ROW_ID: + case API_BY_PACKAGE_NAME: + return Api.CONTENT_ITEM_TYPE; + case API_APPS: return ApiApps.CONTENT_TYPE; @@ -306,6 +346,13 @@ public class KeychainProvider extends ContentProvider { case API_APPS_BY_PACKAGE_NAME: return ApiApps.CONTENT_ITEM_TYPE; + case API_ACCOUNTS: + return ApiAccounts.CONTENT_TYPE; + + case API_ACCOUNTS_BY_ROW_ID: + case API_ACCOUNTS_BY_PACKAGE_NAME: + return ApiAccounts.CONTENT_ITEM_TYPE; + default: throw new UnsupportedOperationException("Unknown uri: " + uri); } @@ -506,7 +553,6 @@ public class KeychainProvider extends ContentProvider { } break; - case PUBLIC_KEY_RING: case SECRET_KEY_RING: qb = buildKeyRingQuery(qb, match); @@ -516,7 +562,6 @@ public class KeychainProvider extends ContentProvider { } break; - case PUBLIC_KEY_RING_BY_ROW_ID: case SECRET_KEY_RING_BY_ROW_ID: qb = buildKeyRingQuery(qb, match); @@ -529,7 +574,6 @@ public class KeychainProvider extends ContentProvider { } break; - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: case SECRET_KEY_RING_BY_MASTER_KEY_ID: qb = buildKeyRingQuery(qb, match); @@ -542,7 +586,6 @@ public class KeychainProvider extends ContentProvider { } break; - case SECRET_KEY_RING_BY_KEY_ID: case PUBLIC_KEY_RING_BY_KEY_ID: qb = buildKeyRingQueryWithSpecificKey(qb, match); @@ -555,7 +598,6 @@ public class KeychainProvider extends ContentProvider { } break; - case SECRET_KEY_RING_BY_EMAILS: case PUBLIC_KEY_RING_BY_EMAILS: qb = buildKeyRingQuery(qb, match); @@ -585,7 +627,6 @@ public class KeychainProvider extends ContentProvider { } break; - case SECRET_KEY_RING_BY_LIKE_EMAIL: case PUBLIC_KEY_RING_BY_LIKE_EMAIL: qb = buildKeyRingQuery(qb, match); @@ -601,7 +642,6 @@ public class KeychainProvider extends ContentProvider { + "))"); break; - case PUBLIC_KEY_RING_KEY: case SECRET_KEY_RING_KEY: qb.setTables(Tables.KEYS); @@ -614,7 +654,6 @@ public class KeychainProvider extends ContentProvider { qb.setProjectionMap(getProjectionMapForKeys()); break; - case PUBLIC_KEY_RING_KEY_BY_ROW_ID: case SECRET_KEY_RING_KEY_BY_ROW_ID: qb.setTables(Tables.KEYS); @@ -630,7 +669,6 @@ public class KeychainProvider extends ContentProvider { qb.setProjectionMap(getProjectionMapForKeys()); break; - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID_USER_ID: qb.setTables(Tables.USER_IDS + " INNER JOIN " + Tables.KEY_RINGS + " ON " + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "." @@ -641,7 +679,6 @@ public class KeychainProvider extends ContentProvider { qb.setProjectionMap(getProjectionMapForUserIds()); break; - case PUBLIC_KEY_RING_USER_ID: case SECRET_KEY_RING_USER_ID: qb.setTables(Tables.USER_IDS); @@ -649,7 +686,6 @@ public class KeychainProvider extends ContentProvider { qb.appendWhereEscapeString(uri.getPathSegments().get(2)); break; - case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: case SECRET_KEY_RING_USER_ID_BY_ROW_ID: qb.setTables(Tables.USER_IDS); @@ -660,7 +696,28 @@ public class KeychainProvider extends ContentProvider { qb.appendWhereEscapeString(uri.getLastPathSegment()); break; + case API: + qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "(" + + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "." + + ApiAccounts.PACKAGE_NAME_FK + " )"); + + break; + case API_BY_ROW_ID: + qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "(" + + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "." + + ApiAccounts.PACKAGE_NAME_FK + " )"); + qb.appendWhere(Tables.API_APPS + "." + BaseColumns._ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); + + break; + case API_BY_PACKAGE_NAME: + qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "(" + + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "." + + ApiAccounts.PACKAGE_NAME_FK + " )"); + qb.appendWhere(Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); + break; case API_APPS: qb.setTables(Tables.API_APPS); @@ -675,10 +732,26 @@ public class KeychainProvider extends ContentProvider { case API_APPS_BY_PACKAGE_NAME: qb.setTables(Tables.API_APPS); qb.appendWhere(ApiApps.PACKAGE_NAME + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + qb.appendWhereEscapeString(uri.getLastPathSegment()); + + break; + case API_ACCOUNTS: + qb.setTables(Tables.API_ACCOUNTS); break; + case API_ACCOUNTS_BY_ROW_ID: + qb.setTables(Tables.API_ACCOUNTS); + qb.appendWhere(BaseColumns._ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); + + break; + case API_ACCOUNTS_BY_PACKAGE_NAME: + qb.setTables(Tables.API_ACCOUNTS); + qb.appendWhere(ApiAppsAccountsColumns.PACKAGE_NAME_FK + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); + + break; default: throw new IllegalArgumentException("Unknown URI " + uri); @@ -770,6 +843,11 @@ public class KeychainProvider extends ContentProvider { rowId = db.insertOrThrow(Tables.API_APPS, null, values); rowUri = ApiApps.buildIdUri(Long.toString(rowId)); + break; + case API_ACCOUNTS: + rowId = db.insertOrThrow(Tables.API_ACCOUNTS, null, values); + rowUri = ApiAccounts.buildIdUri(Long.toString(rowId)); + break; default: throw new UnsupportedOperationException("Unknown uri: " + uri); @@ -836,6 +914,14 @@ public class KeychainProvider extends ContentProvider { count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, true, selection), selectionArgs); break; + case API_ACCOUNTS_BY_ROW_ID: + count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, false, selection), + selectionArgs); + break; + case API_ACCOUNTS_BY_PACKAGE_NAME: + count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, true, selection), + selectionArgs); + break; default: throw new UnsupportedOperationException("Unknown uri: " + uri); } @@ -906,6 +992,14 @@ public class KeychainProvider extends ContentProvider { count = db.update(Tables.API_APPS, values, buildDefaultApiAppsSelection(uri, true, selection), selectionArgs); break; + case API_ACCOUNTS_BY_ROW_ID: + count = db.update(Tables.API_ACCOUNTS, values, + buildDefaultApiAccountsSelection(uri, false, selection), selectionArgs); + break; + case API_ACCOUNTS_BY_PACKAGE_NAME: + count = db.update(Tables.API_ACCOUNTS, values, + buildDefaultApiAccountsSelection(uri, true, selection), selectionArgs); + break; default: throw new UnsupportedOperationException("Unknown uri: " + uri); } @@ -1018,6 +1112,21 @@ public class KeychainProvider extends ContentProvider { } } + private String buildDefaultApiAccountsSelection(Uri uri, boolean packageSelection, String selection) { + String lastPathSegment = uri.getLastPathSegment(); + + String andSelection = ""; + if (!TextUtils.isEmpty(selection)) { + andSelection = " AND (" + selection + ")"; + } + + if (packageSelection) { + return ApiAccounts.PACKAGE_NAME_FK + "=" + lastPathSegment + andSelection; + } else { + return BaseColumns._ID + "=" + lastPathSegment + andSelection; + } + } + // @Override // public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { // int match = mUriMatcher.match(uri); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index e0d007de7..7e8bfbc7b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -809,44 +809,62 @@ public class ProviderHelper { return values; } - public static void insertApiApp(Context context, AppSettings appSettings) { - context.getContentResolver().insert(ApiApps.CONTENT_URI, + private static ContentValues contentValueForApiAccounts(AppSettings appSettings) { + ContentValues values = new ContentValues(); + values.put(KeychainContract.ApiAccounts.PACKAGE_NAME_FK, appSettings.getPackageName()); + values.put(KeychainContract.ApiAccounts.KEY_ID, appSettings.getKeyId()); + values.put(KeychainContract.ApiAccounts.COMPRESSION, appSettings.getCompression()); + values.put(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM, appSettings.getEncryptionAlgorithm()); + values.put(KeychainContract.ApiAccounts.HASH_ALORITHM, appSettings.getHashAlgorithm()); + + return values; + } + + public static void insertApi(Context context, AppSettings appSettings) { + context.getContentResolver().insert(KeychainContract.ApiApps.CONTENT_URI, + contentValueForApiApps(appSettings)); + context.getContentResolver().insert(KeychainContract.ApiAccounts.CONTENT_URI, contentValueForApiApps(appSettings)); } + // TODO: uri not working because it is used for both tables public static void updateApiApp(Context context, AppSettings appSettings, Uri uri) { if (context.getContentResolver().update(uri, contentValueForApiApps(appSettings), null, null) <= 0) { throw new RuntimeException(); } + if (context.getContentResolver().update(uri, contentValueForApiAccounts(appSettings), null, + null) <= 0) { + throw new RuntimeException(); + } } - public static AppSettings getApiAppSettings(Context context, Uri uri) { + public static AppSettings getApiSettings(Context context, Uri uri) { AppSettings settings = null; Cursor cur = context.getContentResolver().query(uri, null, null, null, null); if (cur != null && cur.moveToFirst()) { settings = new AppSettings(); settings.setPackageName(cur.getString(cur - .getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME))); + .getColumnIndex(KeychainContract.Api.PACKAGE_NAME))); settings.setPackageSignature(cur.getBlob(cur - .getColumnIndex(KeychainContract.ApiApps.PACKAGE_SIGNATURE))); - settings.setKeyId(cur.getLong(cur.getColumnIndex(KeychainContract.ApiApps.KEY_ID))); + .getColumnIndex(KeychainContract.Api.PACKAGE_SIGNATURE))); + settings.setKeyId(cur.getLong(cur.getColumnIndex(KeychainContract.Api.KEY_ID))); settings.setCompression(cur.getInt(cur - .getColumnIndexOrThrow(KeychainContract.ApiApps.COMPRESSION))); + .getColumnIndexOrThrow(KeychainContract.Api.COMPRESSION))); settings.setHashAlgorithm(cur.getInt(cur - .getColumnIndexOrThrow(KeychainContract.ApiApps.HASH_ALORITHM))); + .getColumnIndexOrThrow(KeychainContract.Api.HASH_ALORITHM))); settings.setEncryptionAlgorithm(cur.getInt(cur - .getColumnIndexOrThrow(KeychainContract.ApiApps.ENCRYPTION_ALGORITHM))); + .getColumnIndexOrThrow(KeychainContract.Api.ENCRYPTION_ALGORITHM))); } return settings; } - public static byte[] getApiAppSignature(Context context, String packageName) { - Uri queryUri = KeychainContract.ApiApps.buildByPackageNameUri(packageName); + public static byte[] getApiSignature(Context context, String packageName) { + Uri queryUri = KeychainContract.Api.buildByPackageNameUri(packageName); - String[] projection = new String[]{ApiApps.PACKAGE_SIGNATURE}; + String[] projection = new String[]{KeychainContract.Api.PACKAGE_SIGNATURE}; ContentResolver cr = context.getContentResolver(); Cursor cursor = cr.query(queryUri, projection, null, null, null); -- cgit v1.2.3 From 57f9b55677fd0829280a082f739e7d49fbf61db2 Mon Sep 17 00:00:00 2001 From: Sreeram Boyapati Date: Sun, 23 Mar 2014 14:35:48 +0530 Subject: Added can_encrypt check --- .../sufficientlysecure/keychain/ui/ViewKeyMainFragment.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index e140cb21e..e4f707f3c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -324,7 +324,17 @@ public class ViewKeyMainFragment extends Fragment implements mFingerprint.setText(OtherHelper.colorizeFingerprint(fingerprint)); } - + int valid_keys = 0; + data.moveToFirst(); + do{ + if(data.getInt(KEYS_INDEX_CAN_ENCRYPT) == 1){ + valid_keys++; + } + }while(data.moveToNext()); + if(valid_keys == 0){ + mActionEncrypt.setVisibility(View.GONE); + } + Log.i("Valid Encryption keys", Integer.toString(valid_keys)); mKeysAdapter.swapCursor(data); break; -- cgit v1.2.3 From a2048773ee194168594c52c4ea6472b211ef0d5e Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Sun, 23 Mar 2014 19:37:41 +0100 Subject: Fix file decryption interface Actually use mAssumeSymmetricEncryption and set it to false as default. Don't close the file input stream, so we can actually look for PGP encrypted data in the next step. --- .../org/sufficientlysecure/keychain/ui/DecryptActivity.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 3e389c034..ed9735d8c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -443,8 +443,7 @@ public class DecryptActivity extends DrawerActivity { getDecryptionKeyFromInputStream(); // if we need a symmetric passphrase or a passphrase to use a secret key ask for it - if (mSecretKeyId == Id.key.symmetric - || PassphraseCacheService.getCachedPassphrase(this, mSecretKeyId) == null) { + if (mAssumeSymmetricEncryption || PassphraseCacheService.getCachedPassphrase(this, mSecretKeyId) == null) { showPassphraseDialog(); } else { if (mDecryptTarget == Id.target.file) { @@ -494,6 +493,7 @@ public class DecryptActivity extends DrawerActivity { * TODO: Rework function, remove global variables */ private void getDecryptionKeyFromInputStream() { + mAssumeSymmetricEncryption = false; InputStream inStream = null; if (mContentUri != null) { try { @@ -517,13 +517,6 @@ public class DecryptActivity extends DrawerActivity { Log.e(Constants.TAG, "File not found!", e); AppMsg.makeText(this, getString(R.string.error_file_not_found, e.getMessage()), AppMsg.STYLE_ALERT).show(); - } finally { - try { - if (inStream != null) { - inStream.close(); - } - } catch (Exception e) { - } } } else { inStream = new ByteArrayInputStream(mMessage.getText().toString().getBytes()); @@ -540,7 +533,6 @@ public class DecryptActivity extends DrawerActivity { if (mSecretKeyId == Id.key.none) { throw new PgpGeneralException(getString(R.string.error_no_secret_key_found)); } - mAssumeSymmetricEncryption = false; } catch (NoAsymmetricEncryptionException e) { if (inStream.markSupported()) { inStream.reset(); @@ -553,6 +545,7 @@ public class DecryptActivity extends DrawerActivity { mAssumeSymmetricEncryption = true; } } catch (Exception e) { + Log.e(Constants.TAG, "error while reading decryption key from input stream", e); AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()), AppMsg.STYLE_ALERT).show(); } -- cgit v1.2.3 From c9053b97a880ffcc7e7f8a58b9150fa546f87db0 Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Sun, 23 Mar 2014 21:56:18 +0100 Subject: Rename old mentionings of APG-named things Mostly in comments, most importantly: STORE_PATH now ends in /KeychainBlobs instead of /ApgBlobs --- .../java/org/sufficientlysecure/keychain/helper/ExportHelper.java | 4 ++-- .../keychain/provider/KeychainServiceBlobProvider.java | 2 +- .../keychain/service/KeychainIntentService.java | 2 +- .../org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java | 8 ++++---- .../java/org/sufficientlysecure/keychain/ui/DecryptActivity.java | 4 ++-- .../java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 8 ++++---- .../java/org/sufficientlysecure/keychain/ui/EncryptActivity.java | 4 ++-- .../org/sufficientlysecure/keychain/ui/ImportKeysActivity.java | 2 +- .../org/sufficientlysecure/keychain/ui/UploadKeyActivity.java | 4 ++-- .../keychain/ui/dialog/DeleteFileDialogFragment.java | 4 ++-- .../org/sufficientlysecure/keychain/ui/widget/SectionView.java | 4 ++-- 11 files changed, 23 insertions(+), 23 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java index 2bfa796c7..cc240a67b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java @@ -139,7 +139,7 @@ public class ExportHelper { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after exporting is done in ApgService + // Message is received after exporting is done in KeychainIntentService KeychainIntentServiceHandler exportHandler = new KeychainIntentServiceHandler(mActivity, mActivity.getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL, @@ -151,7 +151,7 @@ public class ExportHelper { } }) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java index 6ac61e157..aa30e845d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java @@ -38,7 +38,7 @@ import java.util.List; import java.util.UUID; public class KeychainServiceBlobProvider extends ContentProvider { - private static final String STORE_PATH = Constants.Path.APP_DIR + "/ApgBlobs"; + private static final String STORE_PATH = Constants.Path.APP_DIR + "/KeychainBlobs"; private KeychainServiceBlobDatabase mBlobDatabase = null; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index e26ee3c76..bd3a0421b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -855,7 +855,7 @@ public class KeychainIntentService extends IntentService if (this.mIsCanceled) { return; } - Log.e(Constants.TAG, "ApgService Exception: ", e); + Log.e(Constants.TAG, "KeychainIntentService Exception: ", e); e.printStackTrace(); Bundle data = new Bundle(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index dff4e9d72..5dc06c16d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -327,11 +327,11 @@ public class CertifyKeyActivity extends ActionBarActivity implements intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after signing is done in ApgService + // Message is received after signing is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, getString(R.string.progress_signing), ProgressDialog.STYLE_SPINNER) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { @@ -380,11 +380,11 @@ public class CertifyKeyActivity extends ActionBarActivity implements intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after uploading is done in ApgService + // Message is received after uploading is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index ed9735d8c..9b3b00c19 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -631,11 +631,11 @@ public class DecryptActivity extends DrawerActivity { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after encrypting is done in ApgService + // Message is received after encrypting is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 092a502e1..6eb5b9d2d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -180,7 +180,7 @@ public class EditKeyActivity extends ActionBarActivity { serviceIntent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after generating is done in ApgService + // Message is received after generating is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( this, getResources().getQuantityString(R.plurals.progress_generating, 1), ProgressDialog.STYLE_HORIZONTAL, true, @@ -197,7 +197,7 @@ public class EditKeyActivity extends ActionBarActivity { @Override public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { @@ -540,11 +540,11 @@ public class EditKeyActivity extends ActionBarActivity { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after saving is done in ApgService + // Message is received after saving is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, getString(R.string.progress_saving), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 4ccfd393f..4f18f69d7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -597,11 +597,11 @@ public class EncryptActivity extends DrawerActivity { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after encrypting is done in ApgService + // Message is received after encrypting is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 05bfc613e..834509f53 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -363,7 +363,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa * Import keys with mImportData */ public void importKeys() { - // Message is received after importing is done in ApgService + // Message is received after importing is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( this, getString(R.string.progress_importing), diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java index 2c8f66488..0e231e6a8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java @@ -98,11 +98,11 @@ public class UploadKeyActivity extends ActionBarActivity { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after uploading is done in ApgService + // Message is received after uploading is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java index b067010df..b4c38184c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java @@ -87,11 +87,11 @@ public class DeleteFileDialogFragment extends DialogFragment { false, null); - // Message is received after deleting is done in ApgService + // Message is received after deleting is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(activity, deletingDialog) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index e5b6003b1..1ef178f15 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -256,11 +256,11 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor } }); - // Message is received after generating is done in ApgService + // Message is received after generating is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(mActivity, mGeneratingDialog) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { -- cgit v1.2.3 From fcc7117770be50b1fdaf204bf725a69a111c26d2 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sun, 23 Mar 2014 23:41:08 +0000 Subject: move stuff around, save work --- .../keychain/pgp/PgpKeyOperation.java | 120 +++++++++++---------- 1 file changed, 61 insertions(+), 59 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 8ef2a7452..e64c11852 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -497,12 +497,69 @@ public class PgpKeyOperation { for (int i = 0; i < saveParcel.keys.size(); ++i) { updateProgress(40 + 50 * (i - 1) / (saveParcel.keys.size() - 1), 100); if (saveParcel.moddedKeys[i]) { + //to make public key, use a keygen and temp.publickeyring? + + PGPSecretKey subKey = saveParcel.keys.get(i); + PGPPublicKey subPublicKey = subKey.getPublicKey(); + + PBESecretKeyDecryptor keyDecryptor2; + if (saveParcel.newKeys[i]) { + keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + "".toCharArray()); + } else { + keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + saveParcel.oldPassPhrase.toCharArray()); + } + PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2); + + // TODO: now used without algorithm and creation time?! (APG 1) + PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey, subPrivateKey); + + hashedPacketsGen = new PGPSignatureSubpacketGenerator(); + unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); + + usageId = saveParcel.keysUsages.get(i); + canSign = (usageId & KeyFlags.SIGN_DATA) > 0; //todo - separate function for this + if (canSign) { + Date todayDate = new Date(); //both sig times the same + // cross-certify signing keys + hashedPacketsGen.setSignatureCreationTime(false, todayDate); //set outer creation time + PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); + subHashedPacketsGen.setSignatureCreationTime(false, todayDate); //set inner creation time + PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( + subPublicKey.getAlgorithm(), PGPUtil.SHA1) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); + sGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey); + sGen.setHashedSubpackets(subHashedPacketsGen.generate()); + PGPSignature certification = sGen.generateCertification(masterPublicKey, + subPublicKey); + unhashedPacketsGen.setEmbeddedSignature(false, certification); + } + hashedPacketsGen.setKeyFlags(false, usageId); + + if (saveParcel.keysExpiryDates.get(i) != null) { + GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + creationDate.setTime(subPublicKey.getCreationTime()); + GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(i); + //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c + //here we purposefully ignore partial days in each date - long type has no fractional part! + long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); + if (numDays <= 0) + throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation)); + hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); + } else { + hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, + //this happens anyway + } + + keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate()); + //discard only certain certs //secretkey.replacepublickey with updated public key -//secretkeyring.insertsecretkey with newly signed secret key - } else { -//else nothing, right? } - if (saveParcel.newKeys[i]) { + if (saveParcel.newKeys[i]) { //might not be necessary //set the passphrase to the old one, so we can update the whole keyring passphrase later PBESecretKeyEncryptor keyEncryptorOld = new JcePBESecretKeyEncryptorBuilder( PGPEncryptedData.CAST5, sha1Calc) @@ -520,61 +577,6 @@ public class PgpKeyOperation { } updateProgress(R.string.progress_adding_sub_keys, 40, 100); - for (int i = 1; i < saveParcel.keys.size(); ++i) { - updateProgress(40 + 50 * (i - 1) / (saveParcel.keys.size() - 1), 100); - - PGPSecretKey subKey = saveParcel.keys.get(i); - PGPPublicKey subPublicKey = subKey.getPublicKey(); - - PBESecretKeyDecryptor keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - saveParcel.oldPassPhrase.toCharArray()); - PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2); - - // TODO: now used without algorithm and creation time?! (APG 1) - PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey, subPrivateKey); - - hashedPacketsGen = new PGPSignatureSubpacketGenerator(); - unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); - - usageId = saveParcel.keysUsages.get(i); - canSign = (usageId & KeyFlags.SIGN_DATA) > 0; //todo - separate function for this - if (canSign) { - Date todayDate = new Date(); //both sig times the same - // cross-certify signing keys - hashedPacketsGen.setSignatureCreationTime(false, todayDate); //set outer creation time - PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); - subHashedPacketsGen.setSignatureCreationTime(false, todayDate); //set inner creation time - PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - subPublicKey.getAlgorithm(), PGPUtil.SHA1) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); - sGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey); - sGen.setHashedSubpackets(subHashedPacketsGen.generate()); - PGPSignature certification = sGen.generateCertification(masterPublicKey, - subPublicKey); - unhashedPacketsGen.setEmbeddedSignature(false, certification); - } - hashedPacketsGen.setKeyFlags(false, usageId); - - if (saveParcel.keysExpiryDates.get(i) != null) { - GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - creationDate.setTime(subPublicKey.getCreationTime()); - GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(i); - //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c - //here we purposefully ignore partial days in each date - long type has no fractional part! - long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); - if (numDays <= 0) - throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation)); - hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); - } else { - hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, - //this happens anyway - } - - keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate()); - } - //update the passphrase mKR = PGPSecretKeyRing.copyWithNewPassword(mKR, keyDecryptor, keyEncryptor); updateProgress(R.string.progress_saving_key_ring, 90, 100); -- cgit v1.2.3 From 974514e470d6835ee7a2f6cc34863dae23f16a3e Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Mon, 24 Mar 2014 16:15:28 +0000 Subject: work on saving --- .../keychain/pgp/PgpKeyOperation.java | 45 +++++++++++----------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index e64c11852..3d7826553 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -382,6 +382,8 @@ public class PgpKeyOperation { do we need to remove and add in? */ + //todo: flag changes of master key if IDs changed maybe? + for (PGPSecretKey dKey : saveParcel.deletedKeys) { mKR = PGPSecretKeyRing.removeSecretKey(mKR, dKey); } @@ -484,11 +486,11 @@ public class PgpKeyOperation { PGPContentSignerBuilder certificationSignerBuilder = new JcaPGPContentSignerBuilder( masterKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1); - // Build key encrypter based on passphrase + // Build key encryptor based on old passphrase, as some keys may be unchanged PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder( PGPEncryptedData.CAST5, sha1Calc) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - saveParcel.newPassPhrase.toCharArray()); + saveParcel.oldPassPhrase.toCharArray()); PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(), @@ -497,8 +499,6 @@ public class PgpKeyOperation { for (int i = 0; i < saveParcel.keys.size(); ++i) { updateProgress(40 + 50 * (i - 1) / (saveParcel.keys.size() - 1), 100); if (saveParcel.moddedKeys[i]) { - //to make public key, use a keygen and temp.publickeyring? - PGPSecretKey subKey = saveParcel.keys.get(i); PGPPublicKey subPublicKey = subKey.getPublicKey(); @@ -513,8 +513,6 @@ public class PgpKeyOperation { saveParcel.oldPassPhrase.toCharArray()); } PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2); - - // TODO: now used without algorithm and creation time?! (APG 1) PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey, subPrivateKey); hashedPacketsGen = new PGPSignatureSubpacketGenerator(); @@ -557,28 +555,31 @@ public class PgpKeyOperation { keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate()); //discard only certain certs -//secretkey.replacepublickey with updated public key } - if (saveParcel.newKeys[i]) { //might not be necessary - //set the passphrase to the old one, so we can update the whole keyring passphrase later - PBESecretKeyEncryptor keyEncryptorOld = new JcePBESecretKeyEncryptorBuilder( - PGPEncryptedData.CAST5, sha1Calc) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - saveParcel.oldPassPhrase.toCharArray()); - PBESecretKeyDecryptor keyDecryptorBlank = new JcePBESecretKeyDecryptorBuilder() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - saveParcel.oldPassPhrase.toCharArray()); - saveParcel.keys.set(i, PGPSecretKey.copyWithNewPassword(saveParcel.keys.get(i), - keyDecryptorBlank, keyEncryptorOld)); + } + + PGPSecretKeyRing updatedSecretKeyRing = keyGen.generateSecretKeyRing(); + //finally, update the keyrings + Iterator itr = updatedSecretKeyRing.getSecretKeys(); + while (itr.hasNext()) { + PGPSecretKey theNextKey = itr.next(); + if ((theNextKey.isMasterKey() && saveParcel.moddedKeys[0]) || !theNextKey.isMasterKey()) { + mKR = PGPSecretKeyRing.insertSecretKey(mKR, theNextKey); + pKR = PGPPublicKeyRing.insertPublicKey(pKR, theNextKey.getPublicKey()); } - //finally, update the keyrings - mKR = PGPSecretKeyRing.insertSecretKey(mKR, saveParcel.keys.get(i)); - pKR = PGPPublicKeyRing.insertPublicKey(pKR, saveParcel.keys.get(i).getPublicKey()); } + + updateProgress(R.string.progress_adding_sub_keys, 40, 100); + // Build key encryptor based on new passphrase + PBESecretKeyEncryptor keyEncryptorNew = new JcePBESecretKeyEncryptorBuilder( + PGPEncryptedData.CAST5, sha1Calc) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + saveParcel.newPassPhrase.toCharArray()); + //update the passphrase - mKR = PGPSecretKeyRing.copyWithNewPassword(mKR, keyDecryptor, keyEncryptor); + mKR = PGPSecretKeyRing.copyWithNewPassword(mKR, keyDecryptor, keyEncryptorNew); updateProgress(R.string.progress_saving_key_ring, 90, 100); ProviderHelper.saveKeyRing(mContext, mKR); -- cgit v1.2.3 From 300b90bcac6fbf5b5e416943e538a2c2bc49342c Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Mon, 24 Mar 2014 16:47:02 +0000 Subject: make sure ID info is saved --- .../sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 3d7826553..5f97aa2e5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -368,7 +368,7 @@ public class PgpKeyOperation { } /* - IDs - + IDs - NB This might not need to happen later, if we change the way the primary ID is chosen remove deleted ids if the primary ID changed we need to: remove all of the IDs from the keyring, saving their certifications @@ -382,8 +382,6 @@ public class PgpKeyOperation { do we need to remove and add in? */ - //todo: flag changes of master key if IDs changed maybe? - for (PGPSecretKey dKey : saveParcel.deletedKeys) { mKR = PGPSecretKeyRing.removeSecretKey(mKR, dKey); } @@ -406,7 +404,9 @@ public class PgpKeyOperation { } int user_id_index = 0; + boolean anyIDChanged = false; if (saveParcel.primaryIDChanged) { + anyIDChanged = true; ArrayList> sigList = new ArrayList>(); for (String userId : saveParcel.userIDs) { String orig_id = saveParcel.originalIDs.get(user_id_index); @@ -437,6 +437,7 @@ public class PgpKeyOperation { for (String userId : saveParcel.userIDs) { String orig_id = saveParcel.originalIDs.get(user_id_index); if (!orig_id.equals(userId)) { + anyIDChanged = true; PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); @@ -452,6 +453,12 @@ public class PgpKeyOperation { } } + //update the keyring with the new ID information + if (anyIDChanged) { + pKR = PGPPublicKeyRing.insertPublicKey(pKR, masterPublicKey); + mKR = PGPSecretKeyRing.replacePublicKeys(mKR, pKR); + } + PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey); PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); -- cgit v1.2.3 From 02688f6ebfb07b70656cbe9fe6d723d36f3ffc35 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Mon, 24 Mar 2014 17:41:45 +0000 Subject: comments, slight change to progress bar --- .../sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 5f97aa2e5..adccc5ba3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -380,6 +380,10 @@ public class PgpKeyOperation { remove deleted keys if a key is modified, re-sign it do we need to remove and add in? + + Todo + identify more things which need to be preserved - e.g. trust levels? + user attributes */ for (PGPSecretKey dKey : saveParcel.deletedKeys) { @@ -504,7 +508,7 @@ public class PgpKeyOperation { unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor); for (int i = 0; i < saveParcel.keys.size(); ++i) { - updateProgress(40 + 50 * (i - 1) / (saveParcel.keys.size() - 1), 100); + updateProgress(40 + 50 * i/ saveParcel.keys.size(), 100); if (saveParcel.moddedKeys[i]) { PGPSecretKey subKey = saveParcel.keys.get(i); PGPPublicKey subPublicKey = subKey.getPublicKey(); @@ -561,7 +565,11 @@ public class PgpKeyOperation { } keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate()); - //discard only certain certs + //certifications will be discarded if the key is changed, because I think, for a start, + //they will be invalid. Binding certs are regenerated anyway, and other certs which + //need to be kept are on IDs and attributes + //TODO: don't let revoked keys be edited, other than removed - changing one would result in the + //revocation being wrong? } } @@ -575,10 +583,6 @@ public class PgpKeyOperation { pKR = PGPPublicKeyRing.insertPublicKey(pKR, theNextKey.getPublicKey()); } } - - - updateProgress(R.string.progress_adding_sub_keys, 40, 100); - // Build key encryptor based on new passphrase PBESecretKeyEncryptor keyEncryptorNew = new JcePBESecretKeyEncryptorBuilder( PGPEncryptedData.CAST5, sha1Calc) -- cgit v1.2.3 From e7b3dd64f4f0dbf5841ade521fe654ed8e3e0b26 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Tue, 25 Mar 2014 00:20:35 +0000 Subject: results of debugging, fix several bugs - more needed though... --- .../keychain/pgp/PgpKeyOperation.java | 76 +++++++++++++--------- 1 file changed, 45 insertions(+), 31 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index adccc5ba3..fab456bf8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -386,8 +386,10 @@ public class PgpKeyOperation { user attributes */ - for (PGPSecretKey dKey : saveParcel.deletedKeys) { - mKR = PGPSecretKeyRing.removeSecretKey(mKR, dKey); + if (saveParcel.deletedKeys != null) { + for (PGPSecretKey dKey : saveParcel.deletedKeys) { + mKR = PGPSecretKeyRing.removeSecretKey(mKR, dKey); + } } masterKey = mKR.getSecretKey(); @@ -409,6 +411,31 @@ public class PgpKeyOperation { int user_id_index = 0; boolean anyIDChanged = false; + + PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); + PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); + + hashedPacketsGen.setKeyFlags(true, usageId); + + hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS); + hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS); + hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS); + + if (saveParcel.keysExpiryDates.get(0) != null) { + GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + creationDate.setTime(masterPublicKey.getCreationTime()); + GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(0); + //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c + //here we purposefully ignore partial days in each date - long type has no fractional part! + long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); + if (numDays <= 0) + throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation)); + hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); + } else { + hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, + //this happens anyway + } + if (saveParcel.primaryIDChanged) { anyIDChanged = true; ArrayList> sigList = new ArrayList>(); @@ -427,11 +454,16 @@ public class PgpKeyOperation { PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); - + if (user_id_index == 0) { + sGen.setHashedSubpackets(hashedPacketsGen.generate()); + sGen.setUnhashedSubpackets(unhashedPacketsGen.generate()); + } PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); sigList.add(new Pair(userId, certification)); } - masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, orig_id); + if (!orig_id.equals("")) { + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, orig_id); + } user_id_index++; } for (Pair to_add : sigList) { @@ -448,9 +480,14 @@ public class PgpKeyOperation { PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); - + if (user_id_index == 0) { + sGen.setHashedSubpackets(hashedPacketsGen.generate()); + sGen.setUnhashedSubpackets(unhashedPacketsGen.generate()); + } PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); - masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, orig_id); + if (!orig_id.equals("")) { + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, orig_id); + } masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); } user_id_index++; @@ -465,30 +502,6 @@ public class PgpKeyOperation { PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey); - PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); - PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); - - hashedPacketsGen.setKeyFlags(true, usageId); - - hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS); - hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS); - hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS); - - if (saveParcel.keysExpiryDates.get(0) != null) { - GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - creationDate.setTime(masterPublicKey.getCreationTime()); - GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(0); - //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c - //here we purposefully ignore partial days in each date - long type has no fractional part! - long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); - if (numDays <= 0) - throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation)); - hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); - } else { - hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, - //this happens anyway - } - updateProgress(R.string.progress_building_master_key, 30, 100); // define hashing and signing algos @@ -503,11 +516,12 @@ public class PgpKeyOperation { .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( saveParcel.oldPassPhrase.toCharArray()); + //this generates one more signature than necessary... PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(), unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor); - for (int i = 0; i < saveParcel.keys.size(); ++i) { + for (int i = 1; i < saveParcel.keys.size(); ++i) { updateProgress(40 + 50 * i/ saveParcel.keys.size(), 100); if (saveParcel.moddedKeys[i]) { PGPSecretKey subKey = saveParcel.keys.get(i); -- cgit v1.2.3 From 4e481512c31c60177d3c1b404c97fa8d7a004124 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Tue, 25 Mar 2014 05:26:35 +0100 Subject: Display expiry of subkeys in single key view. --- .../keychain/ui/adapter/ViewKeyKeysAdapter.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java index 068d6e6e9..d925480e9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java @@ -22,6 +22,7 @@ import android.content.res.ColorStateList; import android.database.Cursor; import android.graphics.Color; import android.support.v4.widget.CursorAdapter; +import android.text.format.DateFormat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -31,6 +32,8 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; +import java.util.Date; + public class ViewKeyKeysAdapter extends CursorAdapter { private LayoutInflater mInflater; @@ -42,6 +45,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter { private int mIndexCanEncrypt; private int mIndexCanSign; private int mIndexRevokedKey; + private int mIndexExpiry; private ColorStateList mDefaultTextColor; @@ -76,6 +80,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter { mIndexCanEncrypt = cursor.getColumnIndexOrThrow(Keys.CAN_ENCRYPT); mIndexCanSign = cursor.getColumnIndexOrThrow(Keys.CAN_SIGN); mIndexRevokedKey = cursor.getColumnIndexOrThrow(Keys.IS_REVOKED); + mIndexExpiry = cursor.getColumnIndexOrThrow(Keys.EXPIRY); } } @@ -83,6 +88,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter { public void bindView(View view, Context context, Cursor cursor) { TextView keyId = (TextView) view.findViewById(R.id.keyId); TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails); + TextView keyExpiry = (TextView) view.findViewById(R.id.keyExpiry); ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey); ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey); ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey); @@ -129,6 +135,22 @@ public class ViewKeyKeysAdapter extends CursorAdapter { keyDetails.setTextColor(mDefaultTextColor); revokedKeyIcon.setVisibility(View.GONE); } + + boolean valid = true; + if (!cursor.isNull(mIndexExpiry)) { + Date expiryDate = new Date(cursor.getLong(mIndexExpiry) * 1000); + valid = expiryDate.after(new Date()); + keyExpiry.setText("(" + + context.getString(R.string.label_expiry) + ": " + + DateFormat.getDateFormat(context).format(expiryDate) + ")"); + keyExpiry.setVisibility(View.VISIBLE); + } + else { + keyExpiry.setVisibility(View.GONE); + } + keyId.setEnabled(valid); + keyDetails.setEnabled(valid); + keyExpiry.setEnabled(valid); } @Override -- cgit v1.2.3 From aa35b1f4b5a5198482c9c5a659d357b3ac9a101b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 25 Mar 2014 19:11:20 +0100 Subject: More experimental work on API accounts --- .../org/sufficientlysecure/keychain/Constants.java | 4 +- .../keychain/provider/KeychainContract.java | 61 +++---- .../keychain/provider/KeychainDatabase.java | 3 +- .../keychain/provider/KeychainProvider.java | 108 ++++------- .../keychain/provider/ProviderHelper.java | 99 ++++++---- .../keychain/remote/AccountSettings.java | 85 +++++++++ .../keychain/remote/AppSettings.java | 40 ---- .../keychain/remote/OpenPgpService.java | 48 ++--- .../keychain/remote/RemoteService.java | 8 +- .../remote/ui/AccountSettingsFragment.java | 203 +++++++++++++++++++++ .../keychain/remote/ui/AccountsListFragment.java | 174 ++++++++++++++++++ .../keychain/remote/ui/AppSettingsFragment.java | 87 +-------- .../keychain/remote/ui/AppsListActivity.java | 35 ++++ .../keychain/remote/ui/AppsListFragment.java | 152 +++++++++++++++ .../keychain/remote/ui/RegisteredAppsAdapter.java | 75 -------- .../remote/ui/RegisteredAppsListActivity.java | 35 ---- .../remote/ui/RegisteredAppsListFragment.java | 101 ---------- .../keychain/remote/ui/RemoteServiceActivity.java | 84 +++++++-- 18 files changed, 877 insertions(+), 525 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsAdapter.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListActivity.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListFragment.java (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index ff4abe56a..f9a7962ec 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain; import android.os.Environment; import org.spongycastle.jce.provider.BouncyCastleProvider; -import org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity; +import org.sufficientlysecure.keychain.remote.ui.AppsListActivity; import org.sufficientlysecure.keychain.ui.DecryptActivity; import org.sufficientlysecure.keychain.ui.EncryptActivity; import org.sufficientlysecure.keychain.ui.ImportKeysActivity; @@ -73,7 +73,7 @@ public final class Constants { public static final Class ENCRYPT = EncryptActivity.class; public static final Class DECRYPT = DecryptActivity.class; public static final Class IMPORT_KEYS = ImportKeysActivity.class; - public static final Class REGISTERED_APPS_LIST = RegisteredAppsListActivity.class; + public static final Class REGISTERED_APPS_LIST = AppsListActivity.class; public static final Class[] ARRAY = new Class[]{KEY_LIST, ENCRYPT, DECRYPT, IMPORT_KEYS, REGISTERED_APPS_LIST}; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index aa4c1f131..6e7b76fbe 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.provider; import android.net.Uri; import android.provider.BaseColumns; + import org.sufficientlysecure.keychain.Constants; public class KeychainContract { @@ -59,6 +60,7 @@ public class KeychainContract { } interface ApiAppsAccountsColumns { + String ACCOUNT_NAME = "account_name"; String KEY_ID = "key_id"; // not a database id String ENCRYPTION_ALGORITHM = "encryption_algorithm"; String HASH_ALORITHM = "hash_algorithm"; @@ -90,8 +92,7 @@ public class KeychainContract { public static final String PATH_USER_IDS = "user_ids"; public static final String PATH_KEYS = "keys"; - public static final String BASE_API = "api"; - public static final String PATH_APPS = "apps"; + public static final String BASE_API_APPS = "api_apps"; public static final String PATH_ACCOUNTS = "accounts"; public static final String PATH_BY_PACKAGE_NAME = "package_name"; @@ -257,36 +258,9 @@ public class KeychainContract { } } - /** - * Join over ApiApps with ApiAppsAccounts - */ - public static class Api implements ApiAppsColumns, ApiAppsAccountsColumns, BaseColumns { - public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() - .appendPath(BASE_API).build(); - - /** - * Use if multiple items get returned - */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.apis"; - - /** - * Use if a single item is returned - */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api"; - - public static Uri buildIdUri(String rowId) { - return CONTENT_URI.buildUpon().appendPath(rowId).build(); - } - - public static Uri buildByPackageNameUri(String packageName) { - return CONTENT_URI.buildUpon().appendPath(PATH_BY_PACKAGE_NAME).appendPath(packageName) - .build(); - } - } - public static class ApiApps implements ApiAppsColumns, BaseColumns { public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() - .appendPath(BASE_API).appendPath(PATH_APPS).build(); + .appendPath(BASE_API_APPS).build(); /** * Use if multiple items get returned @@ -303,14 +277,14 @@ public class KeychainContract { } public static Uri buildByPackageNameUri(String packageName) { - return CONTENT_URI.buildUpon().appendPath(PATH_BY_PACKAGE_NAME).appendPath(packageName) - .build(); + return CONTENT_URI.buildUpon().appendPath(PATH_BY_PACKAGE_NAME) + .appendEncodedPath(packageName).build(); } } public static class ApiAccounts implements ApiAppsAccountsColumns, BaseColumns { public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() - .appendPath(BASE_API).appendPath(PATH_ACCOUNTS).build(); + .appendPath(BASE_API_APPS).build(); /** * Use if multiple items get returned @@ -322,13 +296,24 @@ public class KeychainContract { */ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api.account"; - public static Uri buildIdUri(String rowId) { - return CONTENT_URI.buildUpon().appendPath(rowId).build(); +// public static Uri buildUri(String rowIdApp) { +// return CONTENT_URI.buildUpon().appendPath(rowIdApp).appendPath(PATH_ACCOUNTS) +// .build(); +// } +// +// public static Uri buildIdUri(String rowIdApp, String rowId) { +// return CONTENT_URI.buildUpon().appendPath(rowIdApp).appendPath(PATH_ACCOUNTS) +// .appendPath(rowId).build(); +// } + + public static Uri buildBaseUri(String packageName) { + return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS) + .build(); } - public static Uri buildByPackageNameUri(String packageName) { - return CONTENT_URI.buildUpon().appendPath(PATH_BY_PACKAGE_NAME).appendPath(packageName) - .build(); + public static Uri buildByPackageAndAccountUri(String packageName, String accountName) { + return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS) + .appendEncodedPath(accountName).build(); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index e56fa2f8f..ca1a47f0c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -82,10 +82,11 @@ public class KeychainDatabase extends SQLiteOpenHelper { private static final String CREATE_API_APPS_ACCOUNTS = "CREATE TABLE IF NOT EXISTS " + Tables.API_ACCOUNTS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + + ApiAppsAccountsColumns.ACCOUNT_NAME + " TEXT UNIQUE, " + ApiAppsAccountsColumns.KEY_ID + " INT64, " + ApiAppsAccountsColumns.ENCRYPTION_ALGORITHM + " INTEGER, " + ApiAppsAccountsColumns.HASH_ALORITHM + " INTEGER, " - + ApiAppsAccountsColumns.COMPRESSION + " INTEGER" + + ApiAppsAccountsColumns.COMPRESSION + " INTEGER, " + ApiAppsAccountsColumns.PACKAGE_NAME_FK + " TEXT NOT NULL, FOREIGN KEY(" + ApiAppsAccountsColumns.PACKAGE_NAME_FK + ") REFERENCES " + Tables.API_APPS + "(" + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE)"; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index a094b13de..cae76003c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -30,10 +30,8 @@ import android.provider.BaseColumns; import android.text.TextUtils; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.provider.KeychainContract.Api; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; -import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyTypes; @@ -81,15 +79,12 @@ public class KeychainProvider extends ContentProvider { private static final int SECRET_KEY_RING_USER_ID = 221; private static final int SECRET_KEY_RING_USER_ID_BY_ROW_ID = 222; - private static final int API = 301; - private static final int API_BY_ROW_ID = 302; - private static final int API_BY_PACKAGE_NAME = 303; - private static final int API_APPS = 304; - private static final int API_APPS_BY_ROW_ID = 305; - private static final int API_APPS_BY_PACKAGE_NAME = 306; - private static final int API_ACCOUNTS = 307; - private static final int API_ACCOUNTS_BY_ROW_ID = 308; - private static final int API_ACCOUNTS_BY_PACKAGE_NAME = 309; + private static final int API_APPS = 301; + private static final int API_APPS_BY_ROW_ID = 302; + private static final int API_APPS_BY_PACKAGE_NAME = 303; + private static final int API_ACCOUNTS = 304; + private static final int API_ACCOUNTS_BY_ROW_ID = 305; + private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 306; private static final int UNIFIED_KEY_RING = 401; @@ -247,26 +242,18 @@ public class KeychainProvider extends ContentProvider { /** * API apps */ - matcher.addURI(authority, KeychainContract.BASE_API, API); - matcher.addURI(authority, KeychainContract.BASE_API + "/#", API_BY_ROW_ID); - matcher.addURI(authority, KeychainContract.BASE_API + "/" - + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_BY_PACKAGE_NAME); - - matcher.addURI(authority, KeychainContract.BASE_API + "/" - + KeychainContract.PATH_APPS, API_APPS); - matcher.addURI(authority, KeychainContract.BASE_API + "/" - + KeychainContract.PATH_APPS + "/#", API_APPS_BY_ROW_ID); - matcher.addURI(authority, KeychainContract.BASE_API + "/" - + KeychainContract.PATH_APPS + "/" + matcher.addURI(authority, KeychainContract.BASE_API_APPS, API_APPS); + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/#", API_APPS_BY_ROW_ID); + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/" + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_APPS_BY_PACKAGE_NAME); - matcher.addURI(authority, KeychainContract.BASE_API + "/" + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/" + KeychainContract.PATH_ACCOUNTS, API_ACCOUNTS); - matcher.addURI(authority, KeychainContract.BASE_API + "/" + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/" + KeychainContract.PATH_ACCOUNTS + "/#", API_ACCOUNTS_BY_ROW_ID); - matcher.addURI(authority, KeychainContract.BASE_API + "/" + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/" + KeychainContract.PATH_ACCOUNTS + "/" - + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_ACCOUNTS_BY_PACKAGE_NAME); + + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_ACCOUNTS_BY_ACCOUNT_NAME); /** * data stream @@ -332,13 +319,6 @@ public class KeychainProvider extends ContentProvider { case SECRET_KEY_RING_USER_ID_BY_ROW_ID: return UserIds.CONTENT_ITEM_TYPE; - case API: - return Api.CONTENT_TYPE; - - case API_BY_ROW_ID: - case API_BY_PACKAGE_NAME: - return Api.CONTENT_ITEM_TYPE; - case API_APPS: return ApiApps.CONTENT_TYPE; @@ -350,7 +330,7 @@ public class KeychainProvider extends ContentProvider { return ApiAccounts.CONTENT_TYPE; case API_ACCOUNTS_BY_ROW_ID: - case API_ACCOUNTS_BY_PACKAGE_NAME: + case API_ACCOUNTS_BY_ACCOUNT_NAME: return ApiAccounts.CONTENT_ITEM_TYPE; default: @@ -695,28 +675,6 @@ public class KeychainProvider extends ContentProvider { qb.appendWhere(" AND " + BaseColumns._ID + " = "); qb.appendWhereEscapeString(uri.getLastPathSegment()); - break; - case API: - qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "(" - + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "." - + ApiAccounts.PACKAGE_NAME_FK + " )"); - - break; - case API_BY_ROW_ID: - qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "(" - + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "." - + ApiAccounts.PACKAGE_NAME_FK + " )"); - qb.appendWhere(Tables.API_APPS + "." + BaseColumns._ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); - - break; - case API_BY_PACKAGE_NAME: - qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "(" - + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "." - + ApiAccounts.PACKAGE_NAME_FK + " )"); - qb.appendWhere(Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); - break; case API_APPS: qb.setTables(Tables.API_APPS); @@ -740,15 +698,24 @@ public class KeychainProvider extends ContentProvider { break; case API_ACCOUNTS_BY_ROW_ID: - qb.setTables(Tables.API_ACCOUNTS); + qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "(" + + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "." + + ApiAccounts.PACKAGE_NAME_FK + " )"); + qb.appendWhere(Tables.API_APPS + "." + BaseColumns._ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); - qb.appendWhere(BaseColumns._ID + " = "); + qb.appendWhere(" AND " + Tables.API_ACCOUNTS + "." + BaseColumns._ID + " = "); qb.appendWhereEscapeString(uri.getLastPathSegment()); break; - case API_ACCOUNTS_BY_PACKAGE_NAME: - qb.setTables(Tables.API_ACCOUNTS); - qb.appendWhere(ApiAppsAccountsColumns.PACKAGE_NAME_FK + " = "); + case API_ACCOUNTS_BY_ACCOUNT_NAME: + qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "(" + + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "." + + ApiAccounts.PACKAGE_NAME_FK + " )"); + qb.appendWhere(Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + + qb.appendWhere(" AND " + Tables.API_ACCOUNTS + "." + ApiAccounts.ACCOUNT_NAME + " = "); qb.appendWhereEscapeString(uri.getLastPathSegment()); break; @@ -808,13 +775,15 @@ public class KeychainProvider extends ContentProvider { values.put(Keys.TYPE, KeyTypes.PUBLIC); rowId = db.insertOrThrow(Tables.KEYS, null, values); - rowUri = Keys.buildPublicKeysUri(Long.toString(rowId)); + // TODO: this is wrong: +// rowUri = Keys.buildPublicKeysUri(Long.toString(rowId)); sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_USER_ID: rowId = db.insertOrThrow(Tables.USER_IDS, null, values); - rowUri = UserIds.buildPublicUserIdsUri(Long.toString(rowId)); + // TODO: this is wrong: +// rowUri = UserIds.buildPublicUserIdsUri(Long.toString(rowId)); sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; @@ -830,13 +799,15 @@ public class KeychainProvider extends ContentProvider { values.put(Keys.TYPE, KeyTypes.SECRET); rowId = db.insertOrThrow(Tables.KEYS, null, values); - rowUri = Keys.buildSecretKeysUri(Long.toString(rowId)); + // TODO: this is wrong: +// rowUri = Keys.buildSecretKeysUri(Long.toString(rowId)); sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case SECRET_KEY_RING_USER_ID: rowId = db.insertOrThrow(Tables.USER_IDS, null, values); - rowUri = UserIds.buildSecretUserIdsUri(Long.toString(rowId)); + // TODO: this is wrong: +// rowUri = UserIds.buildSecretUserIdsUri(Long.toString(rowId)); break; case API_APPS: @@ -846,7 +817,8 @@ public class KeychainProvider extends ContentProvider { break; case API_ACCOUNTS: rowId = db.insertOrThrow(Tables.API_ACCOUNTS, null, values); - rowUri = ApiAccounts.buildIdUri(Long.toString(rowId)); + // TODO: this is wrong: +// rowUri = ApiAccounts.buildIdUri(Long.toString(rowId)); break; default: @@ -918,7 +890,7 @@ public class KeychainProvider extends ContentProvider { count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, false, selection), selectionArgs); break; - case API_ACCOUNTS_BY_PACKAGE_NAME: + case API_ACCOUNTS_BY_ACCOUNT_NAME: count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, true, selection), selectionArgs); break; @@ -996,7 +968,7 @@ public class KeychainProvider extends ContentProvider { count = db.update(Tables.API_ACCOUNTS, values, buildDefaultApiAccountsSelection(uri, false, selection), selectionArgs); break; - case API_ACCOUNTS_BY_PACKAGE_NAME: + case API_ACCOUNTS_BY_ACCOUNT_NAME: count = db.update(Tables.API_ACCOUNTS, values, buildDefaultApiAccountsSelection(uri, true, selection), selectionArgs); break; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 7e8bfbc7b..e3727b2f8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -22,6 +22,7 @@ import android.database.Cursor; import android.database.DatabaseUtils; import android.net.Uri; import android.os.RemoteException; + import org.spongycastle.bcpg.ArmoredOutputStream; import org.spongycastle.openpgp.*; import org.sufficientlysecure.keychain.Constants; @@ -33,6 +34,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; +import org.sufficientlysecure.keychain.remote.AccountSettings; import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; @@ -469,11 +471,11 @@ public class ProviderHelper { cr.delete(KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)), null, null); } - public static void deleteUnifiedKeyRing(Context context,String masterKeyId,boolean isSecretKey){ - ContentResolver cr= context.getContentResolver(); - cr.delete(KeyRings.buildPublicKeyRingsByMasterKeyIdUri(masterKeyId),null,null); - if(isSecretKey){ - cr.delete(KeyRings.buildSecretKeyRingsByMasterKeyIdUri(masterKeyId),null,null); + public static void deleteUnifiedKeyRing(Context context, String masterKeyId, boolean isSecretKey) { + ContentResolver cr = context.getContentResolver(); + cr.delete(KeyRings.buildPublicKeyRingsByMasterKeyIdUri(masterKeyId), null, null); + if (isSecretKey) { + cr.delete(KeyRings.buildSecretKeyRingsByMasterKeyIdUri(masterKeyId), null, null); } } @@ -504,7 +506,7 @@ public class ProviderHelper { + " AS sign_keys WHERE sign_keys." + Keys.KEY_RING_ROW_ID + " = " + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID + " AND sign_keys." + Keys.CAN_SIGN + " = '1' AND " + Keys.IS_MASTER_KEY - + " = 1) AS sign", }; + + " = 1) AS sign",}; ContentResolver cr = context.getContentResolver(); Cursor cursor = cr.query(queryUri, projection, null, null, null); @@ -801,70 +803,93 @@ public class ProviderHelper { ContentValues values = new ContentValues(); values.put(ApiApps.PACKAGE_NAME, appSettings.getPackageName()); values.put(ApiApps.PACKAGE_SIGNATURE, appSettings.getPackageSignature()); -// values.put(ApiApps.KEY_ID, appSettings.getKeyId()); -// values.put(ApiApps.COMPRESSION, appSettings.getCompression()); -// values.put(ApiApps.ENCRYPTION_ALGORITHM, appSettings.getEncryptionAlgorithm()); -// values.put(ApiApps.HASH_ALORITHM, appSettings.getHashAlgorithm()); - return values; } - private static ContentValues contentValueForApiAccounts(AppSettings appSettings) { + private static ContentValues contentValueForApiAccounts(AccountSettings accSettings) { ContentValues values = new ContentValues(); - values.put(KeychainContract.ApiAccounts.PACKAGE_NAME_FK, appSettings.getPackageName()); - values.put(KeychainContract.ApiAccounts.KEY_ID, appSettings.getKeyId()); - values.put(KeychainContract.ApiAccounts.COMPRESSION, appSettings.getCompression()); - values.put(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM, appSettings.getEncryptionAlgorithm()); - values.put(KeychainContract.ApiAccounts.HASH_ALORITHM, appSettings.getHashAlgorithm()); - + values.put(KeychainContract.ApiAccounts.ACCOUNT_NAME, accSettings.getAccountName()); + values.put(KeychainContract.ApiAccounts.KEY_ID, accSettings.getKeyId()); + values.put(KeychainContract.ApiAccounts.COMPRESSION, accSettings.getCompression()); + values.put(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM, accSettings.getEncryptionAlgorithm()); + values.put(KeychainContract.ApiAccounts.HASH_ALORITHM, accSettings.getHashAlgorithm()); +// values.put(KeychainContract.ApiAccounts.PACKAGE_NAME_FK, accSettings.getPackageName()); return values; } - public static void insertApi(Context context, AppSettings appSettings) { + public static void insertApiApp(Context context, AppSettings appSettings) { context.getContentResolver().insert(KeychainContract.ApiApps.CONTENT_URI, contentValueForApiApps(appSettings)); - context.getContentResolver().insert(KeychainContract.ApiAccounts.CONTENT_URI, - contentValueForApiApps(appSettings)); } - // TODO: uri not working because it is used for both tables + public static void insertApiAccount(Context context, Uri uri, AccountSettings accSettings) { + context.getContentResolver().insert(uri, + contentValueForApiAccounts(accSettings)); + } + public static void updateApiApp(Context context, AppSettings appSettings, Uri uri) { if (context.getContentResolver().update(uri, contentValueForApiApps(appSettings), null, null) <= 0) { throw new RuntimeException(); } - if (context.getContentResolver().update(uri, contentValueForApiAccounts(appSettings), null, + } + + public static void updateApiAccount(Context context, AccountSettings accSettings, Uri uri) { + if (context.getContentResolver().update(uri, contentValueForApiAccounts(accSettings), null, null) <= 0) { throw new RuntimeException(); } } - public static AppSettings getApiSettings(Context context, Uri uri) { + + /** + * Must be an uri pointing to an account + * + * @param context + * @param uri + * @return + */ + public static AppSettings getApiAppSettings(Context context, Uri uri) { AppSettings settings = null; Cursor cur = context.getContentResolver().query(uri, null, null, null, null); if (cur != null && cur.moveToFirst()) { settings = new AppSettings(); - settings.setPackageName(cur.getString(cur - .getColumnIndex(KeychainContract.Api.PACKAGE_NAME))); - settings.setPackageSignature(cur.getBlob(cur - .getColumnIndex(KeychainContract.Api.PACKAGE_SIGNATURE))); - settings.setKeyId(cur.getLong(cur.getColumnIndex(KeychainContract.Api.KEY_ID))); - settings.setCompression(cur.getInt(cur - .getColumnIndexOrThrow(KeychainContract.Api.COMPRESSION))); - settings.setHashAlgorithm(cur.getInt(cur - .getColumnIndexOrThrow(KeychainContract.Api.HASH_ALORITHM))); - settings.setEncryptionAlgorithm(cur.getInt(cur - .getColumnIndexOrThrow(KeychainContract.Api.ENCRYPTION_ALGORITHM))); + settings.setPackageName(cur.getString( + cur.getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME))); + settings.setPackageSignature(cur.getBlob( + cur.getColumnIndex(KeychainContract.ApiApps.PACKAGE_SIGNATURE))); + } + + return settings; + } + + public static AccountSettings getApiAccountSettings(Context context, Uri uri) { + AccountSettings settings = null; + + Cursor cur = context.getContentResolver().query(uri, null, null, null, null); + if (cur != null && cur.moveToFirst()) { + settings = new AccountSettings(); + + settings.setAccountName(cur.getString( + cur.getColumnIndex(KeychainContract.ApiAccounts.ACCOUNT_NAME))); + settings.setKeyId(cur.getLong( + cur.getColumnIndex(KeychainContract.ApiAccounts.KEY_ID))); + settings.setCompression(cur.getInt( + cur.getColumnIndexOrThrow(KeychainContract.ApiAccounts.COMPRESSION))); + settings.setHashAlgorithm(cur.getInt( + cur.getColumnIndexOrThrow(KeychainContract.ApiAccounts.HASH_ALORITHM))); + settings.setEncryptionAlgorithm(cur.getInt( + cur.getColumnIndexOrThrow(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM))); } return settings; } public static byte[] getApiSignature(Context context, String packageName) { - Uri queryUri = KeychainContract.Api.buildByPackageNameUri(packageName); + Uri queryUri = ApiApps.buildByPackageNameUri(packageName); - String[] projection = new String[]{KeychainContract.Api.PACKAGE_SIGNATURE}; + String[] projection = new String[]{ApiApps.PACKAGE_SIGNATURE}; ContentResolver cr = context.getContentResolver(); Cursor cursor = cr.query(queryUri, projection, null, null, null); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java new file mode 100644 index 000000000..832cbc752 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote; + +import org.spongycastle.bcpg.HashAlgorithmTags; +import org.spongycastle.openpgp.PGPEncryptedData; +import org.sufficientlysecure.keychain.Id; + +public class AccountSettings { + private String mAccountName; + private long mKeyId = Id.key.none; + private int mEncryptionAlgorithm; + private int mHashAlgorithm; + private int mCompression; + + public AccountSettings() { + + } + + public AccountSettings(String accountName) { + super(); + this.mAccountName = accountName; + + // defaults: + this.mEncryptionAlgorithm = PGPEncryptedData.AES_256; + this.mHashAlgorithm = HashAlgorithmTags.SHA512; + this.mCompression = Id.choice.compression.zlib; + } + + public String getAccountName() { + return mAccountName; + } + + public void setAccountName(String mAccountName) { + this.mAccountName = mAccountName; + } + + public long getKeyId() { + return mKeyId; + } + + public void setKeyId(long scretKeyId) { + this.mKeyId = scretKeyId; + } + + public int getEncryptionAlgorithm() { + return mEncryptionAlgorithm; + } + + public void setEncryptionAlgorithm(int encryptionAlgorithm) { + this.mEncryptionAlgorithm = encryptionAlgorithm; + } + + public int getHashAlgorithm() { + return mHashAlgorithm; + } + + public void setHashAlgorithm(int hashAlgorithm) { + this.mHashAlgorithm = hashAlgorithm; + } + + public int getCompression() { + return mCompression; + } + + public void setCompression(int compression) { + this.mCompression = compression; + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java index ad48a402b..6c7e51bf0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java @@ -24,10 +24,6 @@ import org.sufficientlysecure.keychain.Id; public class AppSettings { private String mPackageName; private byte[] mPackageSignature; - private long mKeyId = Id.key.none; - private int mEncryptionAlgorithm; - private int mHashAlgorithm; - private int mCompression; public AppSettings() { @@ -37,10 +33,6 @@ public class AppSettings { super(); this.mPackageName = packageName; this.mPackageSignature = packageSignature; - // defaults: - this.mEncryptionAlgorithm = PGPEncryptedData.AES_256; - this.mHashAlgorithm = HashAlgorithmTags.SHA512; - this.mCompression = Id.choice.compression.zlib; } public String getPackageName() { @@ -59,36 +51,4 @@ public class AppSettings { this.mPackageSignature = packageSignature; } - public long getKeyId() { - return mKeyId; - } - - public void setKeyId(long scretKeyId) { - this.mKeyId = scretKeyId; - } - - public int getEncryptionAlgorithm() { - return mEncryptionAlgorithm; - } - - public void setEncryptionAlgorithm(int encryptionAlgorithm) { - this.mEncryptionAlgorithm = encryptionAlgorithm; - } - - public int getHashAlgorithm() { - return mHashAlgorithm; - } - - public void setHashAlgorithm(int hashAlgorithm) { - this.mHashAlgorithm = hashAlgorithm; - } - - public int getCompression() { - return mCompression; - } - - public void setCompression(int compression) { - this.mCompression = compression; - } - } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 9b56a491a..b04e76cbd 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -138,7 +138,7 @@ public class OpenPgpService extends RemoteService { } private Intent signImpl(Intent data, ParcelFileDescriptor input, - ParcelFileDescriptor output, AppSettings appSettings) { + ParcelFileDescriptor output, AccountSettings accSettings) { try { boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); @@ -147,11 +147,11 @@ public class OpenPgpService extends RemoteService { if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) { passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE); } else { - passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); + passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), accSettings.getKeyId()); } if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId()); + Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId()); return passphraseBundle; } @@ -165,9 +165,9 @@ public class OpenPgpService extends RemoteService { // sign-only PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os); builder.enableAsciiArmorOutput(asciiArmor) - .signatureHashAlgorithm(appSettings.getHashAlgorithm()) + .signatureHashAlgorithm(accSettings.getHashAlgorithm()) .signatureForceV3(false) - .signatureKeyId(appSettings.getKeyId()) + .signatureKeyId(accSettings.getKeyId()) .signaturePassphrase(passphrase); builder.build().execute(); } finally { @@ -188,7 +188,7 @@ public class OpenPgpService extends RemoteService { } private Intent encryptAndSignImpl(Intent data, ParcelFileDescriptor input, - ParcelFileDescriptor output, AppSettings appSettings, boolean sign) { + ParcelFileDescriptor output, AccountSettings accSettings, boolean sign) { try { boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); @@ -218,7 +218,7 @@ public class OpenPgpService extends RemoteService { // add own key for encryption keyIds = Arrays.copyOf(keyIds, keyIds.length + 1); - keyIds[keyIds.length - 1] = appSettings.getKeyId(); + keyIds[keyIds.length - 1] = accSettings.getKeyId(); // build InputData and write into OutputStream // Get Input- and OutputStream from ParcelFileDescriptor @@ -230,8 +230,8 @@ public class OpenPgpService extends RemoteService { PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os); builder.enableAsciiArmorOutput(asciiArmor) - .compressionId(appSettings.getCompression()) - .symmetricEncryptionAlgorithm(appSettings.getEncryptionAlgorithm()) + .compressionId(accSettings.getCompression()) + .symmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm()) .encryptionKeyIds(keyIds); if (sign) { @@ -240,18 +240,18 @@ public class OpenPgpService extends RemoteService { passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE); } else { passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), - appSettings.getKeyId()); + accSettings.getKeyId()); } if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId()); + Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId()); return passphraseBundle; } // sign and encrypt - builder.signatureHashAlgorithm(appSettings.getHashAlgorithm()) + builder.signatureHashAlgorithm(accSettings.getHashAlgorithm()) .signatureForceV3(false) - .signatureKeyId(appSettings.getKeyId()) + .signatureKeyId(accSettings.getKeyId()) .signaturePassphrase(passphrase); } else { // encrypt only @@ -277,7 +277,7 @@ public class OpenPgpService extends RemoteService { } private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input, - ParcelFileDescriptor output, AppSettings appSettings) { + ParcelFileDescriptor output, AccountSettings accSettings) { try { // Get Input- and OutputStream from ParcelFileDescriptor InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); @@ -293,7 +293,7 @@ public class OpenPgpService extends RemoteService { PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os); builder.assumeSymmetric(false) // no support for symmetric encryption // allow only the private key for this app for decryption - .enforcedKeyId(appSettings.getKeyId()) + .enforcedKeyId(accSettings.getKeyId()) .passphrase(passphrase); // TODO: currently does not support binary signed-only content @@ -301,7 +301,7 @@ public class OpenPgpService extends RemoteService { if (decryptVerifyResult.isKeyPassphraseNeeded()) { // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId()); + Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId()); return passphraseBundle; } else if (decryptVerifyResult.isSymmetricPassphraseNeeded()) { throw new PgpGeneralException("Decryption of symmetric content not supported by API!"); @@ -433,17 +433,23 @@ public class OpenPgpService extends RemoteService { return errorResult; } - final AppSettings appSettings = getAppSettings(); + String accName; + if (data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME) != null) { + accName = data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME); + } else { + accName = "default"; + } + final AccountSettings accSettings = getAccSettings(accName); String action = data.getAction(); if (OpenPgpApi.ACTION_SIGN.equals(action)) { - return signImpl(data, input, output, appSettings); + return signImpl(data, input, output, accSettings); } else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) { - return encryptAndSignImpl(data, input, output, appSettings, false); + return encryptAndSignImpl(data, input, output, accSettings, false); } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) { - return encryptAndSignImpl(data, input, output, appSettings, true); + return encryptAndSignImpl(data, input, output, accSettings, true); } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) { - return decryptAndVerifyImpl(data, input, output, appSettings); + return decryptAndVerifyImpl(data, input, output, accSettings); } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) { return getKeyImpl(data); } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java index 434fe84c1..7b66a0b5c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java @@ -130,16 +130,16 @@ public abstract class RemoteService extends Service { * * @return */ - protected AppSettings getAppSettings() { + protected AccountSettings getAccSettings(String accountName) { String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid()); // get app settings for this package for (int i = 0; i < callingPackages.length; i++) { String currentPkg = callingPackages[i]; - Uri uri = KeychainContract.ApiApps.buildByPackageNameUri(currentPkg); + Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(currentPkg, accountName); - AppSettings settings = ProviderHelper.getApiAppSettings(this, uri); + AccountSettings settings = ProviderHelper.getApiAccountSettings(this, uri); if (settings != null) { return settings; @@ -210,7 +210,7 @@ public abstract class RemoteService extends Service { throw new WrongPackageSignatureException(e.getMessage()); } - byte[] storedSig = ProviderHelper.getApiAppSignature(this, packageName); + byte[] storedSig = ProviderHelper.getApiSignature(this, packageName); if (Arrays.equals(currentSig, storedSig)) { Log.d(Constants.TAG, "Package signature is correct! (equals signature from database)"); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java new file mode 100644 index 000000000..3d88d216e --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2013-2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.ImageView; +import android.widget.Spinner; +import android.widget.TextView; + +import org.spongycastle.util.encoders.Hex; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.remote.AccountSettings; +import org.sufficientlysecure.keychain.remote.AppSettings; +import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; +import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter; +import org.sufficientlysecure.keychain.util.AlgorithmNames; +import org.sufficientlysecure.keychain.util.Log; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class AccountSettingsFragment extends Fragment implements + SelectSecretKeyLayoutFragment.SelectSecretKeyCallback { + + // model + private AccountSettings mAccSettings; + + // view + private TextView mAppNameView; + private ImageView mAppIconView; + private Spinner mEncryptionAlgorithm; + private Spinner mHashAlgorithm; + private Spinner mCompression; + private TextView mPackageName; + private TextView mPackageSignature; + + private SelectSecretKeyLayoutFragment mSelectKeyFragment; + + KeyValueSpinnerAdapter mEncryptionAdapter; + KeyValueSpinnerAdapter mHashAdapter; + KeyValueSpinnerAdapter mCompressionAdapter; + + public AccountSettings getAccSettings() { + return mAccSettings; + } + + public void setAccSettings(AccountSettings appSettings) { + this.mAccSettings = appSettings; +// setPackage(appSettings.getPackageName()); +// mPackageName.setText(appSettings.getPackageName()); + +// try { +// MessageDigest md = MessageDigest.getInstance("SHA-256"); +// md.update(appSettings.getPackageSignature()); +// byte[] digest = md.digest(); +// String signature = new String(Hex.encode(digest)); +// +// mPackageSignature.setText(signature); +// } catch (NoSuchAlgorithmException e) { +// Log.e(Constants.TAG, "Should not happen!", e); +// } + + mSelectKeyFragment.selectKey(appSettings.getKeyId()); + mEncryptionAlgorithm.setSelection(mEncryptionAdapter.getPosition(appSettings + .getEncryptionAlgorithm())); + mHashAlgorithm.setSelection(mHashAdapter.getPosition(appSettings.getHashAlgorithm())); + mCompression.setSelection(mCompressionAdapter.getPosition(appSettings.getCompression())); + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.api_account_settings_fragment, container, false); + initView(view); + return view; + } + + /** + * Set error String on key selection + * + * @param error + */ + public void setErrorOnSelectKeyFragment(String error) { + mSelectKeyFragment.setError(error); + } + + private void initView(View view) { + mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getFragmentManager().findFragmentById( + R.id.api_account_settings_select_key_fragment); + mSelectKeyFragment.setCallback(this); + + mAppNameView = (TextView) view.findViewById(R.id.api_account_settings_app_name); + mAppIconView = (ImageView) view.findViewById(R.id.api_account_settings_app_icon); + mEncryptionAlgorithm = (Spinner) view + .findViewById(R.id.api_account_settings_encryption_algorithm); + mHashAlgorithm = (Spinner) view.findViewById(R.id.api_account_settings_hash_algorithm); + mCompression = (Spinner) view.findViewById(R.id.api_account_settings_compression); + mPackageName = (TextView) view.findViewById(R.id.api_account_settings_package_name); + mPackageSignature = (TextView) view.findViewById(R.id.api_account_settings_package_signature); + + AlgorithmNames algorithmNames = new AlgorithmNames(getActivity()); + + mEncryptionAdapter = new KeyValueSpinnerAdapter(getActivity(), + algorithmNames.getEncryptionNames()); + mEncryptionAlgorithm.setAdapter(mEncryptionAdapter); + mEncryptionAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() { + + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + mAccSettings.setEncryptionAlgorithm((int) id); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + + mHashAdapter = new KeyValueSpinnerAdapter(getActivity(), algorithmNames.getHashNames()); + mHashAlgorithm.setAdapter(mHashAdapter); + mHashAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() { + + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + mAccSettings.setHashAlgorithm((int) id); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + + mCompressionAdapter = new KeyValueSpinnerAdapter(getActivity(), + algorithmNames.getCompressionNames()); + mCompression.setAdapter(mCompressionAdapter); + mCompression.setOnItemSelectedListener(new OnItemSelectedListener() { + + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + mAccSettings.setCompression((int) id); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + } +// +// private void setPackage(String packageName) { +// PackageManager pm = getActivity().getApplicationContext().getPackageManager(); +// +// // get application name and icon from package manager +// String appName = null; +// Drawable appIcon = null; +// try { +// ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); +// +// appName = (String) pm.getApplicationLabel(ai); +// appIcon = pm.getApplicationIcon(ai); +// } catch (final NameNotFoundException e) { +// // fallback +// appName = packageName; +// } +// mAppNameView.setText(appName); +// mAppIconView.setImageDrawable(appIcon); +// } + + /** + * callback from select secret key fragment + */ + @Override + public void onKeySelected(long secretKeyId) { + mAccSettings.setKeyId(secretKeyId); + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java new file mode 100644 index 000000000..0cec319a5 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.annotation.TargetApi; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.support.v4.app.ListFragment; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.support.v4.widget.CursorAdapter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ImageView; +import android.widget.SimpleCursorAdapter; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; + +// TODO: make compat with < 11 +@TargetApi(Build.VERSION_CODES.HONEYCOMB) +public class AccountsListFragment extends ListFragment implements + LoaderManager.LoaderCallbacks { + + // This is the Adapter being used to display the list's data. + SimpleCursorAdapter mAdapter; + + private String mPackageName; + + public String getPackageName() { + return mPackageName; + } + + public void setPackageName(String packageName) { + this.mPackageName = packageName; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + getListView().setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int position, long id) { + // edit app settings + Intent intent = new Intent(getActivity(), AppSettingsActivity.class); + intent.setData(ContentUris.withAppendedId(ApiApps.CONTENT_URI, id)); + startActivity(intent); + } + }); + + // Give some text to display if there is no data. In a real + // application this would come from a resource. + setEmptyText(getString(R.string.api_no_apps)); + + // We have a menu item to show in action bar. + setHasOptionsMenu(true); + + // Create an empty adapter we will use to display the loaded data. + mAdapter = new SimpleCursorAdapter(getActivity(), + android.R.layout.simple_list_item_1, + null, + new String[]{KeychainContract.ApiAccounts.ACCOUNT_NAME}, + new int[]{android.R.id.text1}, + 0); + setListAdapter(mAdapter); + + // Prepare the loader. Either re-connect with an existing one, + // or start a new one. + getLoaderManager().initLoader(0, null, this); + } + + // These are the Contacts rows that we will retrieve. + static final String[] PROJECTION = new String[]{ + KeychainContract.ApiAccounts._ID, + KeychainContract.ApiAccounts.ACCOUNT_NAME}; + + public Loader onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + // First, pick the base URI to use depending on whether we are + // currently filtering. + Uri baseUri = KeychainContract.ApiAccounts.buildBaseUri(mPackageName); + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null, + KeychainContract.ApiAccounts.ACCOUNT_NAME + " COLLATE LOCALIZED ASC"); + } + + public void onLoadFinished(Loader loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mAdapter.swapCursor(data); + } + + public void onLoaderReset(Loader loader) { + // This is called when the last Cursor provided to onLoadFinished() + // above is about to be closed. We need to make sure we are no + // longer using it. + mAdapter.swapCursor(null); + } + +// private class RegisteredAppsAdapter extends CursorAdapter { +// +// private LayoutInflater mInflater; +// private PackageManager mPM; +// +// public RegisteredAppsAdapter(Context context, Cursor c, int flags) { +// super(context, c, flags); +// +// mInflater = LayoutInflater.from(context); +// mPM = context.getApplicationContext().getPackageManager(); +// } +// +// @Override +// public void bindView(View view, Context context, Cursor cursor) { +// TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name); +// ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon); +// +// String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME)); +// if (packageName != null) { +// // get application name +// try { +// ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0); +// +// text.setText(mPM.getApplicationLabel(ai)); +// icon.setImageDrawable(mPM.getApplicationIcon(ai)); +// } catch (final PackageManager.NameNotFoundException e) { +// // fallback +// text.setText(packageName); +// } +// } else { +// // fallback +// text.setText(packageName); +// } +// +// } +// +// @Override +// public View newView(Context context, Cursor cursor, ViewGroup parent) { +// return mInflater.inflate(R.layout.api_apps_adapter_list_item, null); +// } +// } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java index 8e8f3827b..8bcd83fc7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java @@ -44,8 +44,7 @@ import org.sufficientlysecure.keychain.util.Log; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -public class AppSettingsFragment extends Fragment implements - SelectSecretKeyLayoutFragment.SelectSecretKeyCallback { +public class AppSettingsFragment extends Fragment { // model private AppSettings mAppSettings; @@ -53,18 +52,9 @@ public class AppSettingsFragment extends Fragment implements // view private TextView mAppNameView; private ImageView mAppIconView; - private Spinner mEncryptionAlgorithm; - private Spinner mHashAlgorithm; - private Spinner mCompression; private TextView mPackageName; private TextView mPackageSignature; - private SelectSecretKeyLayoutFragment mSelectKeyFragment; - - KeyValueSpinnerAdapter mEncryptionAdapter; - KeyValueSpinnerAdapter mHashAdapter; - KeyValueSpinnerAdapter mCompressionAdapter; - public AppSettings getAppSettings() { return mAppSettings; } @@ -85,11 +75,6 @@ public class AppSettingsFragment extends Fragment implements Log.e(Constants.TAG, "Should not happen!", e); } - mSelectKeyFragment.selectKey(appSettings.getKeyId()); - mEncryptionAlgorithm.setSelection(mEncryptionAdapter.getPosition(appSettings - .getEncryptionAlgorithm())); - mHashAlgorithm.setSelection(mHashAdapter.getPosition(appSettings.getHashAlgorithm())); - mCompression.setSelection(mCompressionAdapter.getPosition(appSettings.getCompression())); } /** @@ -102,74 +87,13 @@ public class AppSettingsFragment extends Fragment implements return view; } - /** - * Set error String on key selection - * - * @param error - */ - public void setErrorOnSelectKeyFragment(String error) { - mSelectKeyFragment.setError(error); - } private void initView(View view) { - mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getFragmentManager().findFragmentById( - R.id.api_app_settings_select_key_fragment); - mSelectKeyFragment.setCallback(this); - mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name); mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon); - mEncryptionAlgorithm = (Spinner) view - .findViewById(R.id.api_app_settings_encryption_algorithm); - mHashAlgorithm = (Spinner) view.findViewById(R.id.api_app_settings_hash_algorithm); - mCompression = (Spinner) view.findViewById(R.id.api_app_settings_compression); + mPackageName = (TextView) view.findViewById(R.id.api_app_settings_package_name); mPackageSignature = (TextView) view.findViewById(R.id.api_app_settings_package_signature); - - AlgorithmNames algorithmNames = new AlgorithmNames(getActivity()); - - mEncryptionAdapter = new KeyValueSpinnerAdapter(getActivity(), - algorithmNames.getEncryptionNames()); - mEncryptionAlgorithm.setAdapter(mEncryptionAdapter); - mEncryptionAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() { - - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - mAppSettings.setEncryptionAlgorithm((int) id); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - - mHashAdapter = new KeyValueSpinnerAdapter(getActivity(), algorithmNames.getHashNames()); - mHashAlgorithm.setAdapter(mHashAdapter); - mHashAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() { - - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - mAppSettings.setHashAlgorithm((int) id); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - - mCompressionAdapter = new KeyValueSpinnerAdapter(getActivity(), - algorithmNames.getCompressionNames()); - mCompression.setAdapter(mCompressionAdapter); - mCompression.setOnItemSelectedListener(new OnItemSelectedListener() { - - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - mAppSettings.setCompression((int) id); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); } private void setPackage(String packageName) { @@ -191,12 +115,5 @@ public class AppSettingsFragment extends Fragment implements mAppIconView.setImageDrawable(appIcon); } - /** - * callback from select secret key fragment - */ - @Override - public void onKeySelected(long secretKeyId) { - mAppSettings.setKeyId(secretKeyId); - } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java new file mode 100644 index 000000000..f86d279f0 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.os.Bundle; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.DrawerActivity; + +public class AppsListActivity extends DrawerActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.api_apps_list_activity); + + setupDrawerNavigation(savedInstanceState); + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java new file mode 100644 index 000000000..7054a2195 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.ListFragment; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.support.v4.widget.CursorAdapter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ImageView; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; + +public class AppsListFragment extends ListFragment implements + LoaderManager.LoaderCallbacks { + + // This is the Adapter being used to display the list's data. + RegisteredAppsAdapter mAdapter; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + getListView().setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int position, long id) { + // edit app settings + Intent intent = new Intent(getActivity(), AppSettingsActivity.class); + intent.setData(ContentUris.withAppendedId(KeychainContract.ApiApps.CONTENT_URI, id)); + startActivity(intent); + } + }); + + // Give some text to display if there is no data. In a real + // application this would come from a resource. + setEmptyText(getString(R.string.api_no_apps)); + + // We have a menu item to show in action bar. + setHasOptionsMenu(true); + + // Create an empty adapter we will use to display the loaded data. + mAdapter = new RegisteredAppsAdapter(getActivity(), null, 0); + setListAdapter(mAdapter); + + // Prepare the loader. Either re-connect with an existing one, + // or start a new one. + getLoaderManager().initLoader(0, null, this); + } + + // These are the Contacts rows that we will retrieve. + static final String[] PROJECTION = new String[]{ApiApps._ID, ApiApps.PACKAGE_NAME}; + + public Loader onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + // First, pick the base URI to use depending on whether we are + // currently filtering. + Uri baseUri = ApiApps.CONTENT_URI; + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null, + ApiApps.PACKAGE_NAME + " COLLATE LOCALIZED ASC"); + } + + public void onLoadFinished(Loader loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mAdapter.swapCursor(data); + } + + public void onLoaderReset(Loader loader) { + // This is called when the last Cursor provided to onLoadFinished() + // above is about to be closed. We need to make sure we are no + // longer using it. + mAdapter.swapCursor(null); + } + + private class RegisteredAppsAdapter extends CursorAdapter { + + private LayoutInflater mInflater; + private PackageManager mPM; + + public RegisteredAppsAdapter(Context context, Cursor c, int flags) { + super(context, c, flags); + + mInflater = LayoutInflater.from(context); + mPM = context.getApplicationContext().getPackageManager(); + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name); + ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon); + + String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME)); + if (packageName != null) { + // get application name + try { + ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0); + + text.setText(mPM.getApplicationLabel(ai)); + icon.setImageDrawable(mPM.getApplicationIcon(ai)); + } catch (final PackageManager.NameNotFoundException e) { + // fallback + text.setText(packageName); + } + } else { + // fallback + text.setText(packageName); + } + + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return mInflater.inflate(R.layout.api_apps_adapter_list_item, null); + } + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsAdapter.java deleted file mode 100644 index c846343ab..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsAdapter.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.remote.ui; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.database.Cursor; -import android.support.v4.widget.CursorAdapter; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; - -public class RegisteredAppsAdapter extends CursorAdapter { - - private LayoutInflater mInflater; - private PackageManager mPM; - - public RegisteredAppsAdapter(Context context, Cursor c, int flags) { - super(context, c, flags); - - mInflater = LayoutInflater.from(context); - mPM = context.getApplicationContext().getPackageManager(); - } - - @Override - public void bindView(View view, Context context, Cursor cursor) { - TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name); - ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon); - - String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME)); - if (packageName != null) { - // get application name - try { - ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0); - - text.setText(mPM.getApplicationLabel(ai)); - icon.setImageDrawable(mPM.getApplicationIcon(ai)); - } catch (final NameNotFoundException e) { - // fallback - text.setText(packageName); - } - } else { - // fallback - text.setText(packageName); - } - - } - - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - return mInflater.inflate(R.layout.api_apps_adapter_list_item, null); - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListActivity.java deleted file mode 100644 index 79b3c8abc..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListActivity.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.remote.ui; - -import android.os.Bundle; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.ui.DrawerActivity; - -public class RegisteredAppsListActivity extends DrawerActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.api_apps_list_activity); - - setupDrawerNavigation(savedInstanceState); - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListFragment.java deleted file mode 100644 index 99e73e510..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RegisteredAppsListFragment.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.remote.ui; - -import android.content.ContentUris; -import android.content.Intent; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.support.v4.app.ListFragment; -import android.support.v4.app.LoaderManager; -import android.support.v4.content.CursorLoader; -import android.support.v4.content.Loader; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; - -public class RegisteredAppsListFragment extends ListFragment implements - LoaderManager.LoaderCallbacks { - - // This is the Adapter being used to display the list's data. - RegisteredAppsAdapter mAdapter; - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - getListView().setOnItemClickListener(new OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int position, long id) { - // edit app settings - Intent intent = new Intent(getActivity(), AppSettingsActivity.class); - intent.setData(ContentUris.withAppendedId(KeychainContract.ApiApps.CONTENT_URI, id)); - startActivity(intent); - } - }); - - // Give some text to display if there is no data. In a real - // application this would come from a resource. - setEmptyText(getString(R.string.api_no_apps)); - - // We have a menu item to show in action bar. - setHasOptionsMenu(true); - - // Create an empty adapter we will use to display the loaded data. - mAdapter = new RegisteredAppsAdapter(getActivity(), null, 0); - setListAdapter(mAdapter); - - // Prepare the loader. Either re-connect with an existing one, - // or start a new one. - getLoaderManager().initLoader(0, null, this); - } - - // These are the Contacts rows that we will retrieve. - static final String[] PROJECTION = new String[]{ApiApps._ID, ApiApps.PACKAGE_NAME}; - - public Loader onCreateLoader(int id, Bundle args) { - // This is called when a new Loader needs to be created. This - // sample only has one Loader, so we don't care about the ID. - // First, pick the base URI to use depending on whether we are - // currently filtering. - Uri baseUri = ApiApps.CONTENT_URI; - - // Now create and return a CursorLoader that will take care of - // creating a Cursor for the data being displayed. - return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null, - ApiApps.PACKAGE_NAME + " COLLATE LOCALIZED ASC"); - } - - public void onLoadFinished(Loader loader, Cursor data) { - // Swap the new cursor in. (The framework will take care of closing the - // old cursor once we return.) - mAdapter.swapCursor(data); - } - - public void onLoaderReset(Loader loader) { - // This is called when the last Cursor provided to onLoadFinished() - // above is about to be closed. We need to make sure we are no - // longer using it. - mAdapter.swapCursor(null); - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java index 3e19a8ef6..a088ad4b0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java @@ -24,6 +24,7 @@ import android.os.Message; import android.os.Messenger; import android.support.v7.app.ActionBarActivity; import android.view.View; + import org.openintents.openpgp.util.OpenPgpApi; import org.sufficientlysecure.htmltextview.HtmlTextView; import org.sufficientlysecure.keychain.Constants; @@ -31,7 +32,9 @@ import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.remote.AccountSettings; import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; @@ -42,6 +45,8 @@ import java.util.ArrayList; public class RemoteServiceActivity extends ActionBarActivity { public static final String ACTION_REGISTER = Constants.INTENT_PREFIX + "API_ACTIVITY_REGISTER"; + public static final String ACTION_REGISTER_ACCOUNT = Constants.INTENT_PREFIX + + "API_ACTIVITY_REGISTER_ACCOUNT"; public static final String ACTION_CACHE_PASSPHRASE = Constants.INTENT_PREFIX + "API_ACTIVITY_CACHE_PASSPHRASE"; public static final String ACTION_SELECT_PUB_KEYS = Constants.INTENT_PREFIX @@ -58,6 +63,8 @@ public class RemoteServiceActivity extends ActionBarActivity { // register action public static final String EXTRA_PACKAGE_NAME = "package_name"; public static final String EXTRA_PACKAGE_SIGNATURE = "package_signature"; + // create acc action + public static final String EXTRA_ACC_NAME = "acc_name"; // select pub keys action public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "master_key_ids"; public static final String EXTRA_MISSING_USER_IDS = "missing_user_ids"; @@ -66,7 +73,9 @@ public class RemoteServiceActivity extends ActionBarActivity { public static final String EXTRA_ERROR_MESSAGE = "error_message"; // register view - private AppSettingsFragment mSettingsFragment; + private AppSettingsFragment mAppSettingsFragment; + // create acc view + private AccountSettingsFragment mAccSettingsFragment; // select pub keys view private SelectPublicKeyFragment mSelectFragment; @@ -95,13 +104,52 @@ public class RemoteServiceActivity extends ActionBarActivity { public void onClick(View v) { // Allow + ProviderHelper.insertApiApp(RemoteServiceActivity.this, + mAppSettingsFragment.getAppSettings()); + + // give data through for new service call + Intent resultData = extras.getParcelable(EXTRA_DATA); + RemoteServiceActivity.this.setResult(RESULT_OK, resultData); + RemoteServiceActivity.this.finish(); + } + }, R.string.api_register_disallow, R.drawable.ic_action_cancel, + new View.OnClickListener() { + @Override + public void onClick(View v) { + // Disallow + RemoteServiceActivity.this.setResult(RESULT_CANCELED); + RemoteServiceActivity.this.finish(); + } + } + ); + + setContentView(R.layout.api_app_register_activity); + + mAppSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( + R.id.api_app_settings_fragment); + + AppSettings settings = new AppSettings(packageName, packageSignature); + mAppSettingsFragment.setAppSettings(settings); + } else if (ACTION_REGISTER_ACCOUNT.equals(action)) { + final String packageName = extras.getString(EXTRA_PACKAGE_NAME); + final String accName = extras.getString(EXTRA_ACC_NAME); + + // Inflate a "Done"/"Cancel" custom action bar view + ActionBarHelper.setTwoButtonView(getSupportActionBar(), + R.string.api_settings_save, R.drawable.ic_action_done, + new View.OnClickListener() { + @Override + public void onClick(View v) { + // Save + // user needs to select a key! - if (mSettingsFragment.getAppSettings().getKeyId() == Id.key.none) { - mSettingsFragment.setErrorOnSelectKeyFragment( + if (mAccSettingsFragment.getAccSettings().getKeyId() == Id.key.none) { + mAccSettingsFragment.setErrorOnSelectKeyFragment( getString(R.string.api_register_error_select_key)); } else { - ProviderHelper.insertApiApp(RemoteServiceActivity.this, - mSettingsFragment.getAppSettings()); + ProviderHelper.insertApiAccount(RemoteServiceActivity.this, + KeychainContract.ApiAccounts.buildBaseUri(packageName), + mAccSettingsFragment.getAccSettings()); // give data through for new service call Intent resultData = extras.getParcelable(EXTRA_DATA); @@ -109,24 +157,24 @@ public class RemoteServiceActivity extends ActionBarActivity { RemoteServiceActivity.this.finish(); } } - }, R.string.api_register_disallow, R.drawable.ic_action_cancel, - new View.OnClickListener() { - @Override - public void onClick(View v) { - // Disallow - RemoteServiceActivity.this.setResult(RESULT_CANCELED); - RemoteServiceActivity.this.finish(); - } + }, R.string.api_settings_cancel, R.drawable.ic_action_cancel, + new View.OnClickListener() { + @Override + public void onClick(View v) { + // Cancel + RemoteServiceActivity.this.setResult(RESULT_CANCELED); + RemoteServiceActivity.this.finish(); + } } ); - setContentView(R.layout.api_app_register_activity); + setContentView(R.layout.api_account_create_activity); - mSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( - R.id.api_app_settings_fragment); + mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById( + R.id.api_account_settings_fragment); - AppSettings settings = new AppSettings(packageName, packageSignature); - mSettingsFragment.setAppSettings(settings); + AccountSettings settings = new AccountSettings(accName); + mAccSettingsFragment.setAccSettings(settings); } else if (ACTION_CACHE_PASSPHRASE.equals(action)) { long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID); Intent resultData = extras.getParcelable(EXTRA_DATA); -- cgit v1.2.3 From cff35ca84283202d1a0b824b6eb9eaf4231c061a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 25 Mar 2014 21:23:59 +0100 Subject: More experimental work on api accounts --- .../keychain/provider/KeychainContract.java | 11 ++-- .../keychain/provider/KeychainProvider.java | 61 +++++----------------- .../keychain/remote/ui/AccountsListFragment.java | 44 ++++++++-------- .../keychain/remote/ui/AppSettingsActivity.java | 32 +++++++++++- .../keychain/remote/ui/AppsListFragment.java | 30 +++++++++-- 5 files changed, 97 insertions(+), 81 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index 6e7b76fbe..98ce98495 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -95,8 +95,6 @@ public class KeychainContract { public static final String BASE_API_APPS = "api_apps"; public static final String PATH_ACCOUNTS = "accounts"; - public static final String PATH_BY_PACKAGE_NAME = "package_name"; - public static class KeyRings implements KeyRingsColumns, BaseColumns { public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() .appendPath(BASE_KEY_RINGS).build(); @@ -272,13 +270,12 @@ public class KeychainContract { */ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api.apps"; - public static Uri buildIdUri(String rowId) { - return CONTENT_URI.buildUpon().appendPath(rowId).build(); - } +// public static Uri buildIdUri(String rowId) { +// return CONTENT_URI.buildUpon().appendPath(rowId).build(); +// } public static Uri buildByPackageNameUri(String packageName) { - return CONTENT_URI.buildUpon().appendPath(PATH_BY_PACKAGE_NAME) - .appendEncodedPath(packageName).build(); + return CONTENT_URI.buildUpon().appendEncodedPath(packageName).build(); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index cae76003c..005be2fd6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -80,10 +80,8 @@ public class KeychainProvider extends ContentProvider { private static final int SECRET_KEY_RING_USER_ID_BY_ROW_ID = 222; private static final int API_APPS = 301; - private static final int API_APPS_BY_ROW_ID = 302; private static final int API_APPS_BY_PACKAGE_NAME = 303; private static final int API_ACCOUNTS = 304; - private static final int API_ACCOUNTS_BY_ROW_ID = 305; private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 306; private static final int UNIFIED_KEY_RING = 401; @@ -241,19 +239,22 @@ public class KeychainProvider extends ContentProvider { /** * API apps + * + *
+         * api_apps
+         * api_apps/_
+         *
+         * api_apps/_/accounts
+         * api_apps/_/accounts/_
+         * 
*/ matcher.addURI(authority, KeychainContract.BASE_API_APPS, API_APPS); - matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/#", API_APPS_BY_ROW_ID); - matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/" - + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_APPS_BY_PACKAGE_NAME); + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*", API_APPS_BY_PACKAGE_NAME); - matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/" + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/" + KeychainContract.PATH_ACCOUNTS, API_ACCOUNTS); - matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/" - + KeychainContract.PATH_ACCOUNTS + "/#", API_ACCOUNTS_BY_ROW_ID); - matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/" - + KeychainContract.PATH_ACCOUNTS + "/" - + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_ACCOUNTS_BY_ACCOUNT_NAME); + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/" + + KeychainContract.PATH_ACCOUNTS + "/*", API_ACCOUNTS_BY_ACCOUNT_NAME); /** * data stream @@ -322,14 +323,12 @@ public class KeychainProvider extends ContentProvider { case API_APPS: return ApiApps.CONTENT_TYPE; - case API_APPS_BY_ROW_ID: case API_APPS_BY_PACKAGE_NAME: return ApiApps.CONTENT_ITEM_TYPE; case API_ACCOUNTS: return ApiAccounts.CONTENT_TYPE; - case API_ACCOUNTS_BY_ROW_ID: case API_ACCOUNTS_BY_ACCOUNT_NAME: return ApiAccounts.CONTENT_ITEM_TYPE; @@ -679,13 +678,6 @@ public class KeychainProvider extends ContentProvider { case API_APPS: qb.setTables(Tables.API_APPS); - break; - case API_APPS_BY_ROW_ID: - qb.setTables(Tables.API_APPS); - - qb.appendWhere(BaseColumns._ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); - break; case API_APPS_BY_PACKAGE_NAME: qb.setTables(Tables.API_APPS); @@ -696,17 +688,6 @@ public class KeychainProvider extends ContentProvider { case API_ACCOUNTS: qb.setTables(Tables.API_ACCOUNTS); - break; - case API_ACCOUNTS_BY_ROW_ID: - qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "(" - + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "." - + ApiAccounts.PACKAGE_NAME_FK + " )"); - qb.appendWhere(Tables.API_APPS + "." + BaseColumns._ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); - - qb.appendWhere(" AND " + Tables.API_ACCOUNTS + "." + BaseColumns._ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); - break; case API_ACCOUNTS_BY_ACCOUNT_NAME: qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "(" @@ -812,7 +793,7 @@ public class KeychainProvider extends ContentProvider { break; case API_APPS: rowId = db.insertOrThrow(Tables.API_APPS, null, values); - rowUri = ApiApps.buildIdUri(Long.toString(rowId)); +// rowUri = ApiApps.buildIdUri(Long.toString(rowId)); break; case API_ACCOUNTS: @@ -878,18 +859,10 @@ public class KeychainProvider extends ContentProvider { count = db.delete(Tables.KEYS, buildDefaultUserIdsSelection(uri, selection), selectionArgs); break; - case API_APPS_BY_ROW_ID: - count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, false, selection), - selectionArgs); - break; case API_APPS_BY_PACKAGE_NAME: count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, true, selection), selectionArgs); break; - case API_ACCOUNTS_BY_ROW_ID: - count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, false, selection), - selectionArgs); - break; case API_ACCOUNTS_BY_ACCOUNT_NAME: count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, true, selection), selectionArgs); @@ -956,18 +929,10 @@ public class KeychainProvider extends ContentProvider { count = db.update(Tables.USER_IDS, values, buildDefaultUserIdsSelection(uri, selection), selectionArgs); break; - case API_APPS_BY_ROW_ID: - count = db.update(Tables.API_APPS, values, - buildDefaultApiAppsSelection(uri, false, selection), selectionArgs); - break; case API_APPS_BY_PACKAGE_NAME: count = db.update(Tables.API_APPS, values, buildDefaultApiAppsSelection(uri, true, selection), selectionArgs); break; - case API_ACCOUNTS_BY_ROW_ID: - count = db.update(Tables.API_ACCOUNTS, values, - buildDefaultApiAccountsSelection(uri, false, selection), selectionArgs); - break; case API_ACCOUNTS_BY_ACCOUNT_NAME: count = db.update(Tables.API_ACCOUNTS, values, buildDefaultApiAccountsSelection(uri, true, selection), selectionArgs); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java index 0cec319a5..853dc2d3c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java @@ -19,10 +19,7 @@ package org.sufficientlysecure.keychain.remote.ui; import android.annotation.TargetApi; import android.content.ContentUris; -import android.content.Context; import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.os.Build; @@ -31,15 +28,10 @@ import android.support.v4.app.ListFragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; -import android.support.v4.widget.CursorAdapter; -import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; -import android.widget.ImageView; import android.widget.SimpleCursorAdapter; -import android.widget.TextView; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; @@ -50,36 +42,46 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; public class AccountsListFragment extends ListFragment implements LoaderManager.LoaderCallbacks { + private static final String ARG_DATA_URI = "uri"; + // This is the Adapter being used to display the list's data. SimpleCursorAdapter mAdapter; - private String mPackageName; + private Uri mDataUri; - public String getPackageName() { - return mPackageName; - } + /** + * Creates new instance of this fragment + */ + public static AccountsListFragment newInstance(Uri dataUri) { + AccountsListFragment frag = new AccountsListFragment(); + + Bundle args = new Bundle(); + args.putParcelable(ARG_DATA_URI, dataUri); - public void setPackageName(String packageName) { - this.mPackageName = packageName; + frag.setArguments(args); + + return frag; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); + mDataUri = getArguments().getParcelable(ARG_DATA_URI); + getListView().setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int position, long id) { - // edit app settings - Intent intent = new Intent(getActivity(), AppSettingsActivity.class); - intent.setData(ContentUris.withAppendedId(ApiApps.CONTENT_URI, id)); - startActivity(intent); +// // edit app settings +// Intent intent = new Intent(getActivity(), AppSettingsActivity.class); +// intent.setData(ContentUris.withAppendedId(ApiApps.CONTENT_URI, id)); +// startActivity(intent); } }); // Give some text to display if there is no data. In a real // application this would come from a resource. - setEmptyText(getString(R.string.api_no_apps)); + setEmptyText(getString(R.string.api_settings_accounts_empty)); // We have a menu item to show in action bar. setHasOptionsMenu(true); @@ -108,11 +110,11 @@ public class AccountsListFragment extends ListFragment implements // sample only has one Loader, so we don't care about the ID. // First, pick the base URI to use depending on whether we are // currently filtering. - Uri baseUri = KeychainContract.ApiAccounts.buildBaseUri(mPackageName); +// Uri baseUri = KeychainContract.ApiAccounts.buildBaseUri(mPackageName); // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. - return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null, + return new CursorLoader(getActivity(), mDataUri, PROJECTION, null, null, KeychainContract.ApiAccounts.ACCOUNT_NAME + " COLLATE LOCALIZED ASC"); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java index d544455ec..33cde49ba 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java @@ -24,9 +24,11 @@ import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.view.View; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ActionBarHelper; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.util.Log; @@ -35,6 +37,7 @@ public class AppSettingsActivity extends ActionBarActivity { private Uri mAppUri; private AppSettingsFragment mSettingsFragment; + private AccountsListFragment mAccountsListFragment; @Override protected void onCreate(Bundle savedInstanceState) { @@ -64,7 +67,7 @@ public class AppSettingsActivity extends ActionBarActivity { return; } else { Log.d(Constants.TAG, "uri: " + mAppUri); - loadData(mAppUri); + loadData(savedInstanceState, mAppUri); } } @@ -88,9 +91,34 @@ public class AppSettingsActivity extends ActionBarActivity { return super.onOptionsItemSelected(item); } - private void loadData(Uri appUri) { + private void loadData(Bundle savedInstanceState, Uri appUri) { + // TODO: load this also like other fragment with newInstance arguments? AppSettings settings = ProviderHelper.getApiAppSettings(this, appUri); mSettingsFragment.setAppSettings(settings); + + Uri accountsUri = appUri.buildUpon().appendPath(KeychainContract.PATH_ACCOUNTS).build(); + Log.d(Constants.TAG, "accountsUri: " + accountsUri); + startListFragment(savedInstanceState, accountsUri); + } + + private void startListFragment(Bundle savedInstanceState, Uri dataUri) { + // However, if we're being restored from a previous state, + // then we don't need to do anything and should return or else + // we could end up with overlapping fragments. + if (savedInstanceState != null) { + return; + } + + // Create an instance of the fragment + mAccountsListFragment = AccountsListFragment.newInstance(dataUri); + + // Add the fragment to the 'fragment_container' FrameLayout + // NOTE: We use commitAllowingStateLoss() to prevent weird crashes! + getSupportFragmentManager().beginTransaction() + .replace(R.id.api_accounts_list_fragment, mAccountsListFragment) + .commitAllowingStateLoss(); + // do it immediately! + getSupportFragmentManager().executePendingTransactions(); } private void revokeAccess() { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java index 7054a2195..f3fa6e7c6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java @@ -17,7 +17,6 @@ package org.sufficientlysecure.keychain.remote.ui; -import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -38,9 +37,11 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.ImageView; import android.widget.TextView; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; +import org.sufficientlysecure.keychain.util.Log; public class AppsListFragment extends ListFragment implements LoaderManager.LoaderCallbacks { @@ -55,9 +56,10 @@ public class AppsListFragment extends ListFragment implements getListView().setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int position, long id) { + String selectedPackageName = mAdapter.getItemPackageName(position); // edit app settings Intent intent = new Intent(getActivity(), AppSettingsActivity.class); - intent.setData(ContentUris.withAppendedId(KeychainContract.ApiApps.CONTENT_URI, id)); + intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(selectedPackageName)); startActivity(intent); } }); @@ -79,7 +81,10 @@ public class AppsListFragment extends ListFragment implements } // These are the Contacts rows that we will retrieve. - static final String[] PROJECTION = new String[]{ApiApps._ID, ApiApps.PACKAGE_NAME}; + static final String[] PROJECTION = new String[]{ + ApiApps._ID, // 0 + ApiApps.PACKAGE_NAME // 1 + }; public Loader onCreateLoader(int id, Bundle args) { // This is called when a new Loader needs to be created. This @@ -119,6 +124,25 @@ public class AppsListFragment extends ListFragment implements mPM = context.getApplicationContext().getPackageManager(); } + /** + * Similar to CursorAdapter.getItemId(). + * Required to build Uris for api app view, which is not based on row ids + * + * @param position + * @return + */ + public String getItemPackageName(int position) { + if (mDataValid && mCursor != null) { + if (mCursor.moveToPosition(position)) { + return mCursor.getString(1); + } else { + return null; + } + } else { + return null; + } + } + @Override public void bindView(View view, Context context, Cursor cursor) { TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name); -- cgit v1.2.3 From 8c496d3393188559c4ce86d5ac4e3a9b1b2bdff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 25 Mar 2014 21:52:06 +0100 Subject: Fix update and insert for new api content provider --- .../keychain/provider/KeychainProvider.java | 32 ++++++++++------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 005be2fd6..1f725266e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -27,6 +27,7 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.provider.BaseColumns; +import android.support.v4.database.DatabaseUtilsCompat; import android.text.TextUtils; import org.sufficientlysecure.keychain.Constants; @@ -860,11 +861,11 @@ public class KeychainProvider extends ContentProvider { selectionArgs); break; case API_APPS_BY_PACKAGE_NAME: - count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, true, selection), + count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, selection), selectionArgs); break; case API_ACCOUNTS_BY_ACCOUNT_NAME: - count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, true, selection), + count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, selection), selectionArgs); break; default: @@ -931,11 +932,11 @@ public class KeychainProvider extends ContentProvider { break; case API_APPS_BY_PACKAGE_NAME: count = db.update(Tables.API_APPS, values, - buildDefaultApiAppsSelection(uri, true, selection), selectionArgs); + buildDefaultApiAppsSelection(uri, selection), selectionArgs); break; case API_ACCOUNTS_BY_ACCOUNT_NAME: count = db.update(Tables.API_ACCOUNTS, values, - buildDefaultApiAccountsSelection(uri, true, selection), selectionArgs); + buildDefaultApiAccountsSelection(uri, selection), selectionArgs); break; default: throw new UnsupportedOperationException("Unknown uri: " + uri); @@ -1034,34 +1035,29 @@ public class KeychainProvider extends ContentProvider { * @param selection * @return */ - private String buildDefaultApiAppsSelection(Uri uri, boolean packageSelection, String selection) { - String lastPathSegment = uri.getLastPathSegment(); + private String buildDefaultApiAppsSelection(Uri uri, String selection) { + String packageName = DatabaseUtils.sqlEscapeString(uri.getLastPathSegment()); String andSelection = ""; if (!TextUtils.isEmpty(selection)) { andSelection = " AND (" + selection + ")"; } - if (packageSelection) { - return ApiApps.PACKAGE_NAME + "=" + lastPathSegment + andSelection; - } else { - return BaseColumns._ID + "=" + lastPathSegment + andSelection; - } + return ApiApps.PACKAGE_NAME + "=" + packageName + andSelection; } - private String buildDefaultApiAccountsSelection(Uri uri, boolean packageSelection, String selection) { - String lastPathSegment = uri.getLastPathSegment(); + private String buildDefaultApiAccountsSelection(Uri uri, String selection) { + String packageName = DatabaseUtils.sqlEscapeString(uri.getPathSegments().get(2)); + String accountName = DatabaseUtils.sqlEscapeString(uri.getLastPathSegment()); String andSelection = ""; if (!TextUtils.isEmpty(selection)) { andSelection = " AND (" + selection + ")"; } - if (packageSelection) { - return ApiAccounts.PACKAGE_NAME_FK + "=" + lastPathSegment + andSelection; - } else { - return BaseColumns._ID + "=" + lastPathSegment + andSelection; - } + return ApiAccounts.PACKAGE_NAME_FK + "=" + packageName + " AND " + + ApiAccounts.ACCOUNT_NAME + "=" + accountName + + andSelection; } // @Override -- cgit v1.2.3 From dc9fd1221387a4f31ec2ceba615b376b0796ff10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 25 Mar 2014 23:09:57 +0100 Subject: Return account creation intent if account does not exists in db --- .../keychain/provider/KeychainContract.java | 23 ++------ .../keychain/provider/KeychainProvider.java | 5 +- .../keychain/remote/OpenPgpService.java | 3 + .../keychain/remote/RemoteService.java | 69 +++++++++++++++------- .../keychain/remote/ui/RemoteServiceActivity.java | 6 +- 5 files changed, 60 insertions(+), 46 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index 98ce98495..6e4899fc2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -160,6 +160,7 @@ public class KeychainContract { } public static Uri buildSecretKeyRingsByEmailsUri(String emails) { + // TODO: encoded? return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(PATH_BY_EMAILS) .appendPath(emails).build(); } @@ -263,16 +264,12 @@ public class KeychainContract { /** * Use if multiple items get returned */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api.app"; + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api_apps"; /** * Use if a single item is returned */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api.apps"; - -// public static Uri buildIdUri(String rowId) { -// return CONTENT_URI.buildUpon().appendPath(rowId).build(); -// } + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_app"; public static Uri buildByPackageNameUri(String packageName) { return CONTENT_URI.buildUpon().appendEncodedPath(packageName).build(); @@ -286,22 +283,12 @@ public class KeychainContract { /** * Use if multiple items get returned */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api.acoounts"; + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api_app.accounts"; /** * Use if a single item is returned */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api.account"; - -// public static Uri buildUri(String rowIdApp) { -// return CONTENT_URI.buildUpon().appendPath(rowIdApp).appendPath(PATH_ACCOUNTS) -// .build(); -// } -// -// public static Uri buildIdUri(String rowIdApp, String rowId) { -// return CONTENT_URI.buildUpon().appendPath(rowIdApp).appendPath(PATH_ACCOUNTS) -// .appendPath(rowId).build(); -// } + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_app.account"; public static Uri buildBaseUri(String packageName) { return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS) diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 1f725266e..6e5515cab 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -27,7 +27,6 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.provider.BaseColumns; -import android.support.v4.database.DatabaseUtilsCompat; import android.text.TextUtils; import org.sufficientlysecure.keychain.Constants; @@ -243,10 +242,10 @@ public class KeychainProvider extends ContentProvider { * *
          * api_apps
-         * api_apps/_
+         * api_apps/_ (package name)
          *
          * api_apps/_/accounts
-         * api_apps/_/accounts/_
+         * api_apps/_/accounts/_ (account name)
          * 
*/ matcher.addURI(authority, KeychainContract.BASE_API_APPS, API_APPS); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index b04e76cbd..fa6ccf63b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -440,6 +440,9 @@ public class OpenPgpService extends RemoteService { accName = "default"; } final AccountSettings accSettings = getAccSettings(accName); + if (accSettings == null) { + return getCreateAccountIntent(data, accName); + } String action = data.getAction(); if (OpenPgpApi.ACTION_SIGN.equals(action)) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java index 7b66a0b5c..0fd9ee7df 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java @@ -27,6 +27,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.Signature; import android.net.Uri; import android.os.Binder; + import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.util.OpenPgpApi; import org.sufficientlysecure.keychain.Constants; @@ -48,7 +49,6 @@ public abstract class RemoteService extends Service { private static final int PRIVATE_REQUEST_CODE_REGISTER = 651; private static final int PRIVATE_REQUEST_CODE_ERROR = 652; - public Context getContext() { return mContext; } @@ -56,13 +56,9 @@ public abstract class RemoteService extends Service { protected Intent isAllowed(Intent data) { try { if (isCallerAllowed(false)) { - return null; } else { - String[] callingPackages = getPackageManager().getPackagesForUid( - Binder.getCallingUid()); - // TODO: currently simply uses first entry - String packageName = callingPackages[0]; + String packageName = getCurrentCallingPackage(); byte[] packageSignature; try { @@ -85,7 +81,7 @@ public abstract class RemoteService extends Service { intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_REGISTER, intent, 0); + PRIVATE_REQUEST_CODE_REGISTER, intent, 0); // return PendingIntent to be executed by client Intent result = new Intent(); @@ -100,11 +96,11 @@ public abstract class RemoteService extends Service { Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE); intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, - getString(R.string.api_error_wrong_signature)); + getString(R.string.api_error_wrong_signature)); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_ERROR, intent, 0); + PRIVATE_REQUEST_CODE_ERROR, intent, 0); // return PendingIntent to be executed by client Intent result = new Intent(); @@ -126,27 +122,56 @@ public abstract class RemoteService extends Service { } /** - * Retrieves AppSettings from database for the application calling this remote service + * Returns package name associated with the UID, which is assigned to the process that sent you the + * current transaction that is being processed :) + * + * @return package name + */ + private String getCurrentCallingPackage() { + // TODO: + // callingPackages contains more than one entry when sharedUserId has been used... + String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid()); + String currentPkg = callingPackages[0]; + Log.d(Constants.TAG, "currentPkg: " + currentPkg); + + return currentPkg; + } + + /** + * Retrieves AccountSettings from database for the application calling this remote service * * @return */ protected AccountSettings getAccSettings(String accountName) { - String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid()); + String currentPkg = getCurrentCallingPackage(); + Log.d(Constants.TAG, "accountName: " + accountName); - // get app settings for this package - for (int i = 0; i < callingPackages.length; i++) { - String currentPkg = callingPackages[i]; + Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(currentPkg, accountName); - Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(currentPkg, accountName); + AccountSettings settings = ProviderHelper.getApiAccountSettings(this, uri); - AccountSettings settings = ProviderHelper.getApiAccountSettings(this, uri); + return settings; // can be null! + } - if (settings != null) { - return settings; - } - } + protected Intent getCreateAccountIntent(Intent data, String accountName) { + String packageName = getCurrentCallingPackage(); + Log.d(Constants.TAG, "accountName: " + accountName); + + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); + intent.setAction(RemoteServiceActivity.ACTION_CREATE_ACCOUNT); + intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName); + intent.putExtra(RemoteServiceActivity.EXTRA_ACC_NAME, accountName); + intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); + + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), + PRIVATE_REQUEST_CODE_REGISTER, intent, 0); + + // return PendingIntent to be executed by client + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); + result.putExtra(OpenPgpApi.RESULT_INTENT, pi); - return null; + return result; } /** @@ -217,7 +242,7 @@ public abstract class RemoteService extends Service { return true; } else { throw new WrongPackageSignatureException( - "PACKAGE NOT ALLOWED! Signature wrong! (Signature not equals signature from database)"); + "PACKAGE NOT ALLOWED! Signature wrong! (Signature not equals signature from database)"); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java index a088ad4b0..d3ac5cade 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java @@ -45,8 +45,8 @@ import java.util.ArrayList; public class RemoteServiceActivity extends ActionBarActivity { public static final String ACTION_REGISTER = Constants.INTENT_PREFIX + "API_ACTIVITY_REGISTER"; - public static final String ACTION_REGISTER_ACCOUNT = Constants.INTENT_PREFIX - + "API_ACTIVITY_REGISTER_ACCOUNT"; + public static final String ACTION_CREATE_ACCOUNT = Constants.INTENT_PREFIX + + "API_ACTIVITY_CREATE_ACCOUNT"; public static final String ACTION_CACHE_PASSPHRASE = Constants.INTENT_PREFIX + "API_ACTIVITY_CACHE_PASSPHRASE"; public static final String ACTION_SELECT_PUB_KEYS = Constants.INTENT_PREFIX @@ -130,7 +130,7 @@ public class RemoteServiceActivity extends ActionBarActivity { AppSettings settings = new AppSettings(packageName, packageSignature); mAppSettingsFragment.setAppSettings(settings); - } else if (ACTION_REGISTER_ACCOUNT.equals(action)) { + } else if (ACTION_CREATE_ACCOUNT.equals(action)) { final String packageName = extras.getString(EXTRA_PACKAGE_NAME); final String accName = extras.getString(EXTRA_ACC_NAME); -- cgit v1.2.3 From 0edfd7ed48943607ebaaa1dd2c9b1018ace0b024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 25 Mar 2014 23:25:03 +0100 Subject: Temporary fix for inserting by content provider --- .../sufficientlysecure/keychain/provider/KeychainProvider.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 6e5515cab..a5ee723f0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -757,14 +757,14 @@ public class KeychainProvider extends ContentProvider { rowId = db.insertOrThrow(Tables.KEYS, null, values); // TODO: this is wrong: -// rowUri = Keys.buildPublicKeysUri(Long.toString(rowId)); + rowUri = Keys.buildPublicKeysUri(Long.toString(rowId)); sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_USER_ID: rowId = db.insertOrThrow(Tables.USER_IDS, null, values); // TODO: this is wrong: -// rowUri = UserIds.buildPublicUserIdsUri(Long.toString(rowId)); + rowUri = UserIds.buildPublicUserIdsUri(Long.toString(rowId)); sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; @@ -781,14 +781,14 @@ public class KeychainProvider extends ContentProvider { rowId = db.insertOrThrow(Tables.KEYS, null, values); // TODO: this is wrong: -// rowUri = Keys.buildSecretKeysUri(Long.toString(rowId)); + rowUri = Keys.buildSecretKeysUri(Long.toString(rowId)); sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case SECRET_KEY_RING_USER_ID: rowId = db.insertOrThrow(Tables.USER_IDS, null, values); // TODO: this is wrong: -// rowUri = UserIds.buildSecretUserIdsUri(Long.toString(rowId)); + rowUri = UserIds.buildSecretUserIdsUri(Long.toString(rowId)); break; case API_APPS: -- cgit v1.2.3 From 68f035ff88131928cdd0681ba3b1fb4980d9a574 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Tue, 25 Mar 2014 22:28:32 +0000 Subject: allow lists to be subkeys or keyrings --- .../keychain/pgp/PgpConversionHelper.java | 29 +++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java index 20d446824..c7dd7d647 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java @@ -59,13 +59,30 @@ public class PgpConversionHelper { * @return */ public static ArrayList BytesToPGPSecretKeyList(byte[] keysBytes) { - PGPSecretKeyRing keyRing = (PGPSecretKeyRing) BytesToPGPKeyRing(keysBytes); + PGPObjectFactory factory = new PGPObjectFactory(keysBytes); + Object obj = null; ArrayList keys = new ArrayList(); - - @SuppressWarnings("unchecked") - Iterator itr = keyRing.getSecretKeys(); - while (itr.hasNext()) { - keys.add(itr.next()); + try { + while ((obj = factory.nextObject()) != null) { + PGPSecretKey secKey = null; + if(obj instanceof PGPSecretKey) { + if ((secKey = (PGPSecretKey)obj ) == null) { + Log.e(Constants.TAG, "No keys given!"); + } + keys.add(secKey); + } else if(obj instanceof PGPSecretKeyRing) { //master keys are sent as keyrings + PGPSecretKeyRing keyRing = null; + if ((keyRing = (PGPSecretKeyRing)obj) == null) { + Log.e(Constants.TAG, "No keys given!"); + } + @SuppressWarnings("unchecked") + Iterator itr = keyRing.getSecretKeys(); + while (itr.hasNext()) { + keys.add(itr.next()); + } + } + } + } catch (IOException e) { } return keys; -- cgit v1.2.3 From 259a8a63a2efa587c6cbe23ae929d7f8c9478664 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Tue, 25 Mar 2014 22:40:05 +0000 Subject: delete IDs needs to update keyring, flag it --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index fab456bf8..370f66388 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -405,12 +405,13 @@ public class PgpKeyOperation { updateProgress(R.string.progress_certifying_master_key, 20, 100); + boolean anyIDChanged = false; for (String delID : saveParcel.deletedIDs) { + anyIDChanged = true; masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, delID); } int user_id_index = 0; - boolean anyIDChanged = false; PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); -- cgit v1.2.3 From b77e0504aa1308da36df63038d4c05ca9aaebd71 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Tue, 25 Mar 2014 23:01:17 +0000 Subject: allow master key updates by removing old primary ID cert --- .../java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 370f66388..9bf9ecc73 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -376,6 +376,9 @@ public class PgpKeyOperation { else remove changed IDs and add in with new certs + if the master key changed, we need to remove the primary ID certification, so we can add + the new one when it is generated, and they don't conflict + Keys remove deleted keys if a key is modified, re-sign it @@ -495,6 +498,11 @@ public class PgpKeyOperation { } } + if (saveParcel.moddedKeys[0]) { + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, saveParcel.originalIDs.get(0)); + anyIDChanged = true; + } + //update the keyring with the new ID information if (anyIDChanged) { pKR = PGPPublicKeyRing.insertPublicKey(pKR, masterPublicKey); -- cgit v1.2.3 From 028af0c1195b2d6a747874af8cae07dde542dc64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 26 Mar 2014 00:11:49 +0100 Subject: Fix constraints and insert --- .../keychain/provider/KeychainDatabase.java | 25 ++++++++++++---------- .../keychain/provider/KeychainProvider.java | 11 ++++++++-- .../keychain/provider/ProviderHelper.java | 7 ++---- .../keychain/remote/RemoteService.java | 2 +- 4 files changed, 26 insertions(+), 19 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index ca1a47f0c..4abcec435 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -21,6 +21,7 @@ import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.provider.BaseColumns; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns; @@ -63,33 +64,35 @@ public class KeychainDatabase extends SQLiteOpenHelper { + KeysColumns.KEY_DATA + " BLOB," + KeysColumns.RANK + " INTEGER, " + KeysColumns.FINGERPRINT + " BLOB, " - + KeysColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, FOREIGN KEY(" - + KeysColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "(" - + BaseColumns._ID + ") ON DELETE CASCADE)"; + + KeysColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, " + + "FOREIGN KEY(" + KeysColumns.KEY_RING_ROW_ID + ") REFERENCES " + + Tables.KEY_RINGS + "(" + BaseColumns._ID + ") ON DELETE CASCADE)"; private static final String CREATE_USER_IDS = "CREATE TABLE IF NOT EXISTS " + Tables.USER_IDS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + UserIdsColumns.USER_ID + " TEXT, " + UserIdsColumns.RANK + " INTEGER, " - + UserIdsColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, FOREIGN KEY(" - + UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "(" - + BaseColumns._ID + ") ON DELETE CASCADE)"; + + UserIdsColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, " + + "FOREIGN KEY(" + UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES " + + Tables.KEY_RINGS + "(" + BaseColumns._ID + ") ON DELETE CASCADE)"; private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " - + ApiAppsColumns.PACKAGE_NAME + " TEXT UNIQUE, " + + ApiAppsColumns.PACKAGE_NAME + " TEXT NOT NULL UNIQUE, " + ApiAppsColumns.PACKAGE_SIGNATURE + " BLOB)"; private static final String CREATE_API_APPS_ACCOUNTS = "CREATE TABLE IF NOT EXISTS " + Tables.API_ACCOUNTS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " - + ApiAppsAccountsColumns.ACCOUNT_NAME + " TEXT UNIQUE, " + + ApiAppsAccountsColumns.ACCOUNT_NAME + " TEXT NOT NULL, " + ApiAppsAccountsColumns.KEY_ID + " INT64, " + ApiAppsAccountsColumns.ENCRYPTION_ALGORITHM + " INTEGER, " + ApiAppsAccountsColumns.HASH_ALORITHM + " INTEGER, " + ApiAppsAccountsColumns.COMPRESSION + " INTEGER, " - + ApiAppsAccountsColumns.PACKAGE_NAME_FK + " TEXT NOT NULL, FOREIGN KEY(" - + ApiAppsAccountsColumns.PACKAGE_NAME_FK + ") REFERENCES " + Tables.API_APPS + "(" - + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE)"; + + ApiAppsAccountsColumns.PACKAGE_NAME_FK + " TEXT NOT NULL, " + + "UNIQUE(" + ApiAppsAccountsColumns.ACCOUNT_NAME + ", " + + ApiAppsAccountsColumns.PACKAGE_NAME_FK + "), " + + "FOREIGN KEY(" + ApiAppsAccountsColumns.PACKAGE_NAME_FK + ") REFERENCES " + + Tables.API_APPS + "(" + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE)"; KeychainDatabase(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index a5ee723f0..6469da978 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -694,7 +694,7 @@ public class KeychainProvider extends ContentProvider { + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "." + ApiAccounts.PACKAGE_NAME_FK + " )"); qb.appendWhere(Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + qb.appendWhereEscapeString(uri.getPathSegments().get(1)); qb.appendWhere(" AND " + Tables.API_ACCOUNTS + "." + ApiAccounts.ACCOUNT_NAME + " = "); qb.appendWhereEscapeString(uri.getLastPathSegment()); @@ -797,6 +797,13 @@ public class KeychainProvider extends ContentProvider { break; case API_ACCOUNTS: + // set foreign key automatically based on given uri + // e.g., api_apps/com.example.app/accounts/ + String packageName = uri.getPathSegments().get(1); + values.put(ApiAccounts.PACKAGE_NAME_FK, packageName); + + Log.d(Constants.TAG, "provider packageName: " + packageName); + rowId = db.insertOrThrow(Tables.API_ACCOUNTS, null, values); // TODO: this is wrong: // rowUri = ApiAccounts.buildIdUri(Long.toString(rowId)); @@ -1046,7 +1053,7 @@ public class KeychainProvider extends ContentProvider { } private String buildDefaultApiAccountsSelection(Uri uri, String selection) { - String packageName = DatabaseUtils.sqlEscapeString(uri.getPathSegments().get(2)); + String packageName = DatabaseUtils.sqlEscapeString(uri.getPathSegments().get(1)); String accountName = DatabaseUtils.sqlEscapeString(uri.getLastPathSegment()); String andSelection = ""; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index e3727b2f8..71f74b8d8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -813,7 +813,6 @@ public class ProviderHelper { values.put(KeychainContract.ApiAccounts.COMPRESSION, accSettings.getCompression()); values.put(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM, accSettings.getEncryptionAlgorithm()); values.put(KeychainContract.ApiAccounts.HASH_ALORITHM, accSettings.getHashAlgorithm()); -// values.put(KeychainContract.ApiAccounts.PACKAGE_NAME_FK, accSettings.getPackageName()); return values; } @@ -823,8 +822,7 @@ public class ProviderHelper { } public static void insertApiAccount(Context context, Uri uri, AccountSettings accSettings) { - context.getContentResolver().insert(uri, - contentValueForApiAccounts(accSettings)); + context.getContentResolver().insert(uri, contentValueForApiAccounts(accSettings)); } public static void updateApiApp(Context context, AppSettings appSettings, Uri uri) { @@ -841,7 +839,6 @@ public class ProviderHelper { } } - /** * Must be an uri pointing to an account * @@ -886,7 +883,7 @@ public class ProviderHelper { return settings; } - public static byte[] getApiSignature(Context context, String packageName) { + public static byte[] getApiAppSignature(Context context, String packageName) { Uri queryUri = ApiApps.buildByPackageNameUri(packageName); String[] projection = new String[]{ApiApps.PACKAGE_SIGNATURE}; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java index 0fd9ee7df..7e935d317 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java @@ -235,7 +235,7 @@ public abstract class RemoteService extends Service { throw new WrongPackageSignatureException(e.getMessage()); } - byte[] storedSig = ProviderHelper.getApiSignature(this, packageName); + byte[] storedSig = ProviderHelper.getApiAppSignature(this, packageName); if (Arrays.equals(currentSig, storedSig)) { Log.d(Constants.TAG, "Package signature is correct! (equals signature from database)"); -- cgit v1.2.3 From 930d722013c36104300bfe4773798ae3d5089b6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 26 Mar 2014 00:40:13 +0100 Subject: Simplify can encrypt check --- .../keychain/ui/ViewKeyMainFragment.java | 43 ++++++++++++---------- 1 file changed, 24 insertions(+), 19 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index 8a4f2758a..691be5fa9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -32,7 +32,9 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ListView; import android.widget.TextView; + import com.beardedhen.androidbootstrap.BootstrapButton; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.OtherHelper; @@ -143,7 +145,7 @@ public class ViewKeyMainFragment extends Fragment implements editIntent.setData( KeychainContract .KeyRings.buildSecretKeyRingsByMasterKeyIdUri( - Long.toString(masterKeyId))); + Long.toString(masterKeyId))); editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY); startActivityForResult(editIntent, 0); } @@ -192,27 +194,27 @@ public class ViewKeyMainFragment extends Fragment implements static final String[] KEYRING_PROJECTION = new String[]{KeychainContract.KeyRings._ID, KeychainContract.KeyRings.MASTER_KEY_ID, - KeychainContract.UserIds.USER_ID}; + KeychainContract.UserIds.USER_ID}; static final int KEYRING_INDEX_ID = 0; static final int KEYRING_INDEX_MASTER_KEY_ID = 1; static final int KEYRING_INDEX_USER_ID = 2; static final String[] USER_IDS_PROJECTION = new String[]{ - KeychainContract.UserIds._ID, - KeychainContract.UserIds.USER_ID, - KeychainContract.UserIds.RANK, + KeychainContract.UserIds._ID, + KeychainContract.UserIds.USER_ID, + KeychainContract.UserIds.RANK, }; static final String USER_IDS_SORT_ORDER = KeychainContract.UserIds.RANK + " COLLATE LOCALIZED ASC"; static final String[] KEYS_PROJECTION = new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID, - KeychainContract.Keys.IS_MASTER_KEY, KeychainContract.Keys.ALGORITHM, - KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY, - KeychainContract.Keys.CAN_SIGN, KeychainContract.Keys.CAN_ENCRYPT, - KeychainContract.Keys.IS_REVOKED, KeychainContract.Keys.CREATION, - KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT}; + KeychainContract.Keys.IS_MASTER_KEY, KeychainContract.Keys.ALGORITHM, + KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY, + KeychainContract.Keys.CAN_SIGN, KeychainContract.Keys.CAN_ENCRYPT, + KeychainContract.Keys.IS_REVOKED, KeychainContract.Keys.CREATION, + KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT}; static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC"; static final int KEYS_INDEX_ID = 0; static final int KEYS_INDEX_KEY_ID = 1; @@ -297,7 +299,7 @@ public class ViewKeyMainFragment extends Fragment implements mCreation.setText( DateFormat.getDateFormat(getActivity().getApplicationContext()).format( - creationDate)); + creationDate)); } // get expiry date from EXPIRY @@ -308,7 +310,7 @@ public class ViewKeyMainFragment extends Fragment implements mExpiry.setText( DateFormat.getDateFormat(getActivity().getApplicationContext()).format( - expiryDate)); + expiryDate)); } String algorithmStr = PgpKeyHelper.getAlgorithmInfo( @@ -324,17 +326,20 @@ public class ViewKeyMainFragment extends Fragment implements mFingerprint.setText(PgpKeyHelper.colorizeFingerprint(fingerprint)); } - int valid_keys = 0; + + // hide encrypt button if no encryption key is available + boolean canEncrypt = false; data.moveToFirst(); - do{ - if(data.getInt(KEYS_INDEX_CAN_ENCRYPT) == 1){ - valid_keys++; + do { + if (data.getInt(KEYS_INDEX_CAN_ENCRYPT) == 1) { + canEncrypt = true; + break; } - }while(data.moveToNext()); - if(valid_keys == 0){ + } while (data.moveToNext()); + if (!canEncrypt) { mActionEncrypt.setVisibility(View.GONE); } - Log.i("Valid Encryption keys", Integer.toString(valid_keys)); + mKeysAdapter.swapCursor(data); break; -- cgit v1.2.3 From 4923c9b8e3e78c888cde438a5f9aac7155ed30f5 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Wed, 26 Mar 2014 00:29:39 +0000 Subject: add original primary ID field to parcel --- .../org/sufficientlysecure/keychain/service/SaveKeyringParcel.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index ae481aa80..c99284847 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -41,6 +41,7 @@ public class SaveKeyringParcel implements Parcelable { public String oldPassPhrase; public boolean[] newKeys; public ArrayList keys; + public String originalPrimaryID; public SaveKeyringParcel() {} @@ -62,6 +63,7 @@ public class SaveKeyringParcel implements Parcelable { oldPassPhrase = source.readString(); newKeys = source.createBooleanArray(); keys = PgpConversionHelper.BytesToPGPSecretKeyList(source.createByteArray()); + originalPrimaryID = source.readString(); } @Override @@ -82,6 +84,7 @@ public class SaveKeyringParcel implements Parcelable { destination.writeString(oldPassPhrase); destination.writeBooleanArray(newKeys); destination.writeByteArray(PgpConversionHelper.PGPSecretKeyArrayListToBytes(keys)); + destination.writeString(originalPrimaryID); } public static final Creator CREATOR = new Creator() { -- cgit v1.2.3 From 9542dc0e12a61535c2866a70cdd9266aff6cd9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 26 Mar 2014 13:07:32 +0100 Subject: Accounts API, user interface --- .../remote/ui/AccountSettingsActivity.java | 110 ++++++++++++++++++ .../keychain/remote/ui/AccountsListFragment.java | 127 ++++++++++----------- .../keychain/remote/ui/AppSettingsActivity.java | 38 +++--- .../keychain/remote/ui/AppSettingsFragment.java | 10 +- 4 files changed, 194 insertions(+), 91 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java new file mode 100644 index 000000000..1092c7dc8 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.support.v7.app.ActionBarActivity; +import android.view.MenuItem; +import android.view.View; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.ActionBarHelper; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.remote.AccountSettings; +import org.sufficientlysecure.keychain.util.Log; + +public class AccountSettingsActivity extends ActionBarActivity { + private Uri mAccountUri; + + private AccountSettingsFragment mAccountSettingsFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Inflate a "Done" custom action bar + ActionBarHelper.setOneButtonView(getSupportActionBar(), + R.string.api_settings_save, R.drawable.ic_action_done, + new View.OnClickListener() { + @Override + public void onClick(View v) { + // "Done" + save(); + } + }); + + setContentView(R.layout.api_account_settings_activity); + + mAccountSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById( + R.id.api_account_settings_fragment); + + Intent intent = getIntent(); + mAccountUri = intent.getData(); + if (mAccountUri == null) { + Log.e(Constants.TAG, "Intent data missing. Should be Uri of app!"); + finish(); + return; + } else { + Log.d(Constants.TAG, "uri: " + mAccountUri); + loadData(savedInstanceState, mAccountUri); + } + } + +// @Override +// public boolean onCreateOptionsMenu(Menu menu) { +// super.onCreateOptionsMenu(menu); +// getMenuInflater().inflate(R.menu.api_app_settings, menu); +// return true; +// } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_api_settings_revoke: + deleteAccount(); + return true; + case R.id.menu_api_settings_cancel: + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + private void loadData(Bundle savedInstanceState, Uri accountUri) { + // TODO: load this also like other fragment with newInstance arguments? + AccountSettings settings = ProviderHelper.getApiAccountSettings(this, accountUri); + mAccountSettingsFragment.setAccSettings(settings); + } + + private void deleteAccount() { + if (getContentResolver().delete(mAccountUri, null, null) <= 0) { + throw new RuntimeException(); + } + finish(); + } + + private void save() { + ProviderHelper.updateApiAccount(this, mAccountSettingsFragment.getAccSettings(), mAccountUri); + + finish(); + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java index 853dc2d3c..22ee7db76 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Dominik Schürmann + * Copyright (C) 2014 Dominik Schürmann * * 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 @@ -17,35 +17,35 @@ package org.sufficientlysecure.keychain.remote.ui; -import android.annotation.TargetApi; -import android.content.ContentUris; +import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.support.v4.app.ListFragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; +import android.support.v4.widget.CursorAdapter; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; -import android.widget.SimpleCursorAdapter; +import android.widget.TextView; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; +import org.sufficientlysecure.keychain.util.Log; -// TODO: make compat with < 11 -@TargetApi(Build.VERSION_CODES.HONEYCOMB) public class AccountsListFragment extends ListFragment implements LoaderManager.LoaderCallbacks { private static final String ARG_DATA_URI = "uri"; // This is the Adapter being used to display the list's data. - SimpleCursorAdapter mAdapter; + AccountsAdapter mAdapter; private Uri mDataUri; @@ -72,10 +72,14 @@ public class AccountsListFragment extends ListFragment implements getListView().setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int position, long id) { -// // edit app settings -// Intent intent = new Intent(getActivity(), AppSettingsActivity.class); -// intent.setData(ContentUris.withAppendedId(ApiApps.CONTENT_URI, id)); -// startActivity(intent); + String selectedAccountName = mAdapter.getItemAccountName(position); + Uri accountUri = mDataUri.buildUpon().appendEncodedPath(selectedAccountName).build(); + Log.d(Constants.TAG, "accountUri: " + accountUri); + + // edit account settings + Intent intent = new Intent(getActivity(), AccountSettingsActivity.class); + intent.setData(accountUri); + startActivity(intent); } }); @@ -87,12 +91,7 @@ public class AccountsListFragment extends ListFragment implements setHasOptionsMenu(true); // Create an empty adapter we will use to display the loaded data. - mAdapter = new SimpleCursorAdapter(getActivity(), - android.R.layout.simple_list_item_1, - null, - new String[]{KeychainContract.ApiAccounts.ACCOUNT_NAME}, - new int[]{android.R.id.text1}, - 0); + mAdapter = new AccountsAdapter(getActivity(), null, 0); setListAdapter(mAdapter); // Prepare the loader. Either re-connect with an existing one, @@ -102,15 +101,13 @@ public class AccountsListFragment extends ListFragment implements // These are the Contacts rows that we will retrieve. static final String[] PROJECTION = new String[]{ - KeychainContract.ApiAccounts._ID, - KeychainContract.ApiAccounts.ACCOUNT_NAME}; + KeychainContract.ApiAccounts._ID, // 0 + KeychainContract.ApiAccounts.ACCOUNT_NAME // 1 + }; public Loader onCreateLoader(int id, Bundle args) { // This is called when a new Loader needs to be created. This // sample only has one Loader, so we don't care about the ID. - // First, pick the base URI to use depending on whether we are - // currently filtering. -// Uri baseUri = KeychainContract.ApiAccounts.buildBaseUri(mPackageName); // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. @@ -131,46 +128,46 @@ public class AccountsListFragment extends ListFragment implements mAdapter.swapCursor(null); } -// private class RegisteredAppsAdapter extends CursorAdapter { -// -// private LayoutInflater mInflater; -// private PackageManager mPM; -// -// public RegisteredAppsAdapter(Context context, Cursor c, int flags) { -// super(context, c, flags); -// -// mInflater = LayoutInflater.from(context); -// mPM = context.getApplicationContext().getPackageManager(); -// } -// -// @Override -// public void bindView(View view, Context context, Cursor cursor) { -// TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name); -// ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon); -// -// String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME)); -// if (packageName != null) { -// // get application name -// try { -// ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0); -// -// text.setText(mPM.getApplicationLabel(ai)); -// icon.setImageDrawable(mPM.getApplicationIcon(ai)); -// } catch (final PackageManager.NameNotFoundException e) { -// // fallback -// text.setText(packageName); -// } -// } else { -// // fallback -// text.setText(packageName); -// } -// -// } -// -// @Override -// public View newView(Context context, Cursor cursor, ViewGroup parent) { -// return mInflater.inflate(R.layout.api_apps_adapter_list_item, null); -// } -// } + private class AccountsAdapter extends CursorAdapter { + private LayoutInflater mInflater; + + public AccountsAdapter(Context context, Cursor c, int flags) { + super(context, c, flags); + + mInflater = LayoutInflater.from(context); + } + + /** + * Similar to CursorAdapter.getItemId(). + * Required to build Uris for api app view, which is not based on row ids + * + * @param position + * @return + */ + public String getItemAccountName(int position) { + if (mDataValid && mCursor != null) { + if (mCursor.moveToPosition(position)) { + return mCursor.getString(1); + } else { + return null; + } + } else { + return null; + } + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + TextView text = (TextView) view.findViewById(R.id.api_accounts_adapter_item_name); + + String accountName = cursor.getString(1); + text.setText(accountName); + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return mInflater.inflate(R.layout.api_accounts_adapter_list_item, null); + } + } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java index 33cde49ba..e4b943734 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java @@ -18,16 +18,17 @@ package org.sufficientlysecure.keychain.remote.ui; import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; +import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; -import android.view.View; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote.AppSettings; @@ -43,16 +44,11 @@ public class AppSettingsActivity extends ActionBarActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // Inflate a "Done" custom action bar - ActionBarHelper.setOneButtonView(getSupportActionBar(), - R.string.api_settings_save, R.drawable.ic_action_done, - new View.OnClickListener() { - @Override - public void onClick(View v) { - // "Done" - save(); - } - }); + // let the actionbar look like Android's contact app + ActionBar actionBar = getSupportActionBar(); + actionBar.setDisplayHomeAsUpEnabled(true); + actionBar.setIcon(android.R.color.transparent); + actionBar.setHomeButtonEnabled(true); setContentView(R.layout.api_app_settings_activity); @@ -96,6 +92,18 @@ public class AppSettingsActivity extends ActionBarActivity { AppSettings settings = ProviderHelper.getApiAppSettings(this, appUri); mSettingsFragment.setAppSettings(settings); + String appName; + PackageManager pm = getPackageManager(); + try { + ApplicationInfo ai = pm.getApplicationInfo(settings.getPackageName(), 0); + appName = (String) pm.getApplicationLabel(ai); + } catch (PackageManager.NameNotFoundException e) { + // fallback + appName = settings.getPackageName(); + } + setTitle(appName); + + Uri accountsUri = appUri.buildUpon().appendPath(KeychainContract.PATH_ACCOUNTS).build(); Log.d(Constants.TAG, "accountsUri: " + accountsUri); startListFragment(savedInstanceState, accountsUri); @@ -128,10 +136,4 @@ public class AppSettingsActivity extends ActionBarActivity { finish(); } - private void save() { - ProviderHelper.updateApiApp(this, mSettingsFragment.getAppSettings(), mAppUri); - - finish(); - } - } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java index 8bcd83fc7..5a6151d88 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java @@ -26,19 +26,13 @@ import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ImageView; -import android.widget.Spinner; import android.widget.TextView; import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.remote.AppSettings; -import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; -import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter; -import org.sufficientlysecure.keychain.util.AlgorithmNames; import org.sufficientlysecure.keychain.util.Log; import java.security.MessageDigest; @@ -100,14 +94,14 @@ public class AppSettingsFragment extends Fragment { PackageManager pm = getActivity().getApplicationContext().getPackageManager(); // get application name and icon from package manager - String appName = null; + String appName; Drawable appIcon = null; try { ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); appName = (String) pm.getApplicationLabel(ai); appIcon = pm.getApplicationIcon(ai); - } catch (final NameNotFoundException e) { + } catch (NameNotFoundException e) { // fallback appName = packageName; } -- cgit v1.2.3 From 8d23ba968a033cd29ac63216ad4f2179222b0cbf Mon Sep 17 00:00:00 2001 From: uberspot Date: Wed, 26 Mar 2014 14:06:40 +0200 Subject: add strike through text for revoked or expired keys and disable views for revoked keys as well --- .../keychain/helper/OtherHelper.java | 14 +++++++------ .../keychain/ui/adapter/ViewKeyKeysAdapter.java | 23 ++++++++++++++++++---- 2 files changed, 27 insertions(+), 10 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java index d0ba20ea6..b31a889f0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java @@ -17,18 +17,14 @@ package org.sufficientlysecure.keychain.helper; -import android.graphics.Color; import android.os.Bundle; -import android.text.Spannable; import android.text.SpannableStringBuilder; -import android.text.style.ForegroundColorSpan; +import android.text.Spanned; +import android.text.style.StrikethroughSpan; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.util.Log; -import java.security.DigestException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.Iterator; import java.util.Set; @@ -65,4 +61,10 @@ public class OtherHelper { } } + public static SpannableStringBuilder strikeOutText(CharSequence text) { + SpannableStringBuilder sb = new SpannableStringBuilder(text); + sb.setSpan(new StrikethroughSpan(), 0, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); + return sb; + } + } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java index d925480e9..ed4113fb8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java @@ -29,6 +29,7 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; @@ -126,28 +127,42 @@ public class ViewKeyKeysAdapter extends CursorAdapter { signIcon.setVisibility(View.VISIBLE); } + boolean valid = true; if (cursor.getInt(mIndexRevokedKey) > 0) { revokedKeyIcon.setVisibility(View.VISIBLE); + keyId.setTextColor(Color.RED); keyDetails.setTextColor(Color.RED); + keyExpiry.setTextColor(Color.RED); + + valid = false; } else { keyId.setTextColor(mDefaultTextColor); keyDetails.setTextColor(mDefaultTextColor); + keyExpiry.setTextColor(mDefaultTextColor); + revokedKeyIcon.setVisibility(View.GONE); } - boolean valid = true; if (!cursor.isNull(mIndexExpiry)) { Date expiryDate = new Date(cursor.getLong(mIndexExpiry) * 1000); - valid = expiryDate.after(new Date()); + + valid = valid && expiryDate.after(new Date()); keyExpiry.setText("(" + - context.getString(R.string.label_expiry) + ": " + - DateFormat.getDateFormat(context).format(expiryDate) + ")"); + context.getString(R.string.label_expiry) + ": " + + DateFormat.getDateFormat(context).format(expiryDate) + ")"); + keyExpiry.setVisibility(View.VISIBLE); } else { keyExpiry.setVisibility(View.GONE); } + // if key is expired or revoked, strike through text + if (!valid) { + keyId.setText(OtherHelper.strikeOutText(keyId.getText())); + keyDetails.setText(OtherHelper.strikeOutText(keyDetails.getText())); + keyExpiry.setText(OtherHelper.strikeOutText(keyExpiry.getText())); + } keyId.setEnabled(valid); keyDetails.setEnabled(valid); keyExpiry.setEnabled(valid); -- cgit v1.2.3 From 92a4d0e914d7cd132b7e755caf914710969e512d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 26 Mar 2014 13:21:29 +0100 Subject: Part 2 of basic user interface for api accounts --- .../remote/ui/AccountSettingsActivity.java | 17 ++--- .../remote/ui/AccountSettingsFragment.java | 79 +++++++++------------- 2 files changed, 41 insertions(+), 55 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java index 1092c7dc8..671a3e0aa 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java @@ -21,6 +21,7 @@ import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; +import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -68,20 +69,20 @@ public class AccountSettingsActivity extends ActionBarActivity { } } -// @Override -// public boolean onCreateOptionsMenu(Menu menu) { -// super.onCreateOptionsMenu(menu); -// getMenuInflater().inflate(R.menu.api_app_settings, menu); -// return true; -// } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + getMenuInflater().inflate(R.menu.api_account_settings, menu); + return true; + } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - case R.id.menu_api_settings_revoke: + case R.id.menu_account_settings_delete: deleteAccount(); return true; - case R.id.menu_api_settings_cancel: + case R.id.menu_account_settings_cancel: finish(); return true; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java index 3d88d216e..91e74f2bf 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java @@ -17,6 +17,7 @@ package org.sufficientlysecure.keychain.remote.ui; +import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -32,11 +33,14 @@ import android.widget.ImageView; import android.widget.Spinner; import android.widget.TextView; +import com.beardedhen.androidbootstrap.BootstrapButton; + import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.remote.AccountSettings; import org.sufficientlysecure.keychain.remote.AppSettings; +import org.sufficientlysecure.keychain.ui.EditKeyActivity; import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter; import org.sufficientlysecure.keychain.util.AlgorithmNames; @@ -52,15 +56,13 @@ public class AccountSettingsFragment extends Fragment implements private AccountSettings mAccSettings; // view - private TextView mAppNameView; - private ImageView mAppIconView; + private TextView mAccNameView; private Spinner mEncryptionAlgorithm; private Spinner mHashAlgorithm; private Spinner mCompression; - private TextView mPackageName; - private TextView mPackageSignature; private SelectSecretKeyLayoutFragment mSelectKeyFragment; + private BootstrapButton mCreateKeyButton; KeyValueSpinnerAdapter mEncryptionAdapter; KeyValueSpinnerAdapter mHashAdapter; @@ -70,27 +72,15 @@ public class AccountSettingsFragment extends Fragment implements return mAccSettings; } - public void setAccSettings(AccountSettings appSettings) { - this.mAccSettings = appSettings; -// setPackage(appSettings.getPackageName()); -// mPackageName.setText(appSettings.getPackageName()); - -// try { -// MessageDigest md = MessageDigest.getInstance("SHA-256"); -// md.update(appSettings.getPackageSignature()); -// byte[] digest = md.digest(); -// String signature = new String(Hex.encode(digest)); -// -// mPackageSignature.setText(signature); -// } catch (NoSuchAlgorithmException e) { -// Log.e(Constants.TAG, "Should not happen!", e); -// } - - mSelectKeyFragment.selectKey(appSettings.getKeyId()); - mEncryptionAlgorithm.setSelection(mEncryptionAdapter.getPosition(appSettings + public void setAccSettings(AccountSettings accountSettings) { + this.mAccSettings = accountSettings; + + mAccNameView.setText(accountSettings.getAccountName()); + mSelectKeyFragment.selectKey(accountSettings.getKeyId()); + mEncryptionAlgorithm.setSelection(mEncryptionAdapter.getPosition(accountSettings .getEncryptionAlgorithm())); - mHashAlgorithm.setSelection(mHashAdapter.getPosition(appSettings.getHashAlgorithm())); - mCompression.setSelection(mCompressionAdapter.getPosition(appSettings.getCompression())); + mHashAlgorithm.setSelection(mHashAdapter.getPosition(accountSettings.getHashAlgorithm())); + mCompression.setSelection(mCompressionAdapter.getPosition(accountSettings.getCompression())); } /** @@ -117,14 +107,19 @@ public class AccountSettingsFragment extends Fragment implements R.id.api_account_settings_select_key_fragment); mSelectKeyFragment.setCallback(this); - mAppNameView = (TextView) view.findViewById(R.id.api_account_settings_app_name); - mAppIconView = (ImageView) view.findViewById(R.id.api_account_settings_app_icon); + mAccNameView = (TextView) view.findViewById(R.id.api_account_settings_acc_name); mEncryptionAlgorithm = (Spinner) view .findViewById(R.id.api_account_settings_encryption_algorithm); mHashAlgorithm = (Spinner) view.findViewById(R.id.api_account_settings_hash_algorithm); mCompression = (Spinner) view.findViewById(R.id.api_account_settings_compression); - mPackageName = (TextView) view.findViewById(R.id.api_account_settings_package_name); - mPackageSignature = (TextView) view.findViewById(R.id.api_account_settings_package_signature); + mCreateKeyButton = (BootstrapButton) view.findViewById(R.id.api_account_settings_create_key); + + mCreateKeyButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + createKey(); + } + }); AlgorithmNames algorithmNames = new AlgorithmNames(getActivity()); @@ -172,25 +167,15 @@ public class AccountSettingsFragment extends Fragment implements } }); } -// -// private void setPackage(String packageName) { -// PackageManager pm = getActivity().getApplicationContext().getPackageManager(); -// -// // get application name and icon from package manager -// String appName = null; -// Drawable appIcon = null; -// try { -// ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); -// -// appName = (String) pm.getApplicationLabel(ai); -// appIcon = pm.getApplicationIcon(ai); -// } catch (final NameNotFoundException e) { -// // fallback -// appName = packageName; -// } -// mAppNameView.setText(appName); -// mAppIconView.setImageDrawable(appIcon); -// } + + private void createKey() { + Intent intent = new Intent(getActivity(), EditKeyActivity.class); + intent.setAction(EditKeyActivity.ACTION_CREATE_KEY); + intent.putExtra(EditKeyActivity.EXTRA_GENERATE_DEFAULT_KEYS, true); + // set default user id to account name TODO: not working currently in EditKey + intent.putExtra(EditKeyActivity.EXTRA_USER_IDS, mAccSettings.getAccountName()); + startActivityForResult(intent, 0); + } /** * callback from select secret key fragment -- cgit v1.2.3 From f10235220d08628892432142ad632512e3f2c68e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 26 Mar 2014 13:32:36 +0100 Subject: Forgot resource --- .../keychain/remote/ui/AccountSettingsFragment.java | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java index 91e74f2bf..0931e6e31 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java @@ -18,10 +18,6 @@ package org.sufficientlysecure.keychain.remote.ui; import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; @@ -29,25 +25,17 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; -import android.widget.ImageView; import android.widget.Spinner; import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; -import org.spongycastle.util.encoders.Hex; -import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.remote.AccountSettings; -import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.ui.EditKeyActivity; import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter; import org.sufficientlysecure.keychain.util.AlgorithmNames; -import org.sufficientlysecure.keychain.util.Log; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; public class AccountSettingsFragment extends Fragment implements SelectSecretKeyLayoutFragment.SelectSecretKeyCallback { -- cgit v1.2.3 From c8b77171051a4b7403c3a62e526798a40e250898 Mon Sep 17 00:00:00 2001 From: uberspot Date: Wed, 26 Mar 2014 14:45:56 +0200 Subject: fix capability icons and remove red text for revoked keys --- .../sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java | 4 ---- 1 file changed, 4 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java index ed4113fb8..9d60c1530 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java @@ -131,10 +131,6 @@ public class ViewKeyKeysAdapter extends CursorAdapter { if (cursor.getInt(mIndexRevokedKey) > 0) { revokedKeyIcon.setVisibility(View.VISIBLE); - keyId.setTextColor(Color.RED); - keyDetails.setTextColor(Color.RED); - keyExpiry.setTextColor(Color.RED); - valid = false; } else { keyId.setTextColor(mDefaultTextColor); -- cgit v1.2.3 From ec3459733180a5d83805b6fe9ddf5571f7b0380f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 26 Mar 2014 14:11:28 +0100 Subject: Make PendingIntents with FLAG_CANCEL_CURRENT and FLAG_ONE_SHOT --- .../keychain/remote/OpenPgpService.java | 29 ++++++------- .../keychain/remote/RemoteService.java | 24 ++++++----- .../keychain/remote/ui/AppSettingsFragment.java | 47 ++++++++++------------ .../keychain/remote/ui/RemoteServiceActivity.java | 1 + 4 files changed, 50 insertions(+), 51 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index fa6ccf63b..ad0c658ad 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -23,6 +23,7 @@ import android.database.Cursor; import android.net.Uri; import android.os.IBinder; import android.os.ParcelFileDescriptor; + import org.openintents.openpgp.IOpenPgpService; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.OpenPgpSignatureResult; @@ -47,10 +48,6 @@ import java.util.ArrayList; public class OpenPgpService extends RemoteService { - private static final int PRIVATE_REQUEST_CODE_PASSPHRASE = 551; - private static final int PRIVATE_REQUEST_CODE_USER_IDS = 552; - private static final int PRIVATE_REQUEST_CODE_GET_KEYS = 553; - /** * Search database for key ids based on emails. * @@ -100,8 +97,9 @@ public class OpenPgpService extends RemoteService { intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, dublicateUserIds); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - PendingIntent pi = PendingIntent.getActivity - (getBaseContext(), PRIVATE_REQUEST_CODE_USER_IDS, intent, 0); + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, + intent, + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); // return PendingIntent to be executed by client Intent result = new Intent(); @@ -127,8 +125,9 @@ public class OpenPgpService extends RemoteService { intent.putExtra(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, keyId); // pass params through to activity that it can be returned again later to repeat pgp operation intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - PendingIntent pi = PendingIntent.getActivity - (getBaseContext(), PRIVATE_REQUEST_CODE_PASSPHRASE, intent, 0); + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, + intent, + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); // return PendingIntent to be executed by client Intent result = new Intent(); @@ -211,7 +210,7 @@ public class OpenPgpService extends RemoteService { Intent result = new Intent(); result.putExtra(OpenPgpApi.RESULT_ERROR, new OpenPgpError(OpenPgpError.GENERIC_ERROR, - "Missing parameter user_ids or key_ids!")); + "Missing parameter user_ids or key_ids!")); result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); return result; } @@ -318,8 +317,9 @@ public class OpenPgpService extends RemoteService { intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo"); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_GET_KEYS, intent, 0); + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, + intent, + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); result.putExtra(OpenPgpApi.RESULT_INTENT, pi); } @@ -358,8 +358,9 @@ public class OpenPgpService extends RemoteService { intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo"); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_GET_KEYS, intent, 0); + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, + intent, + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); result.putExtra(OpenPgpApi.RESULT_INTENT, pi); result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); @@ -408,7 +409,7 @@ public class OpenPgpService extends RemoteService { if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != OpenPgpApi.API_VERSION) { Intent result = new Intent(); OpenPgpError error = new OpenPgpError - (OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!"); + (OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!"); result.putExtra(OpenPgpApi.RESULT_ERROR, error); result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); return result; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java index 7e935d317..8cea3cd21 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java @@ -46,9 +46,6 @@ import java.util.Arrays; public abstract class RemoteService extends Service { Context mContext; - private static final int PRIVATE_REQUEST_CODE_REGISTER = 651; - private static final int PRIVATE_REQUEST_CODE_ERROR = 652; - public Context getContext() { return mContext; } @@ -59,6 +56,7 @@ public abstract class RemoteService extends Service { return null; } else { String packageName = getCurrentCallingPackage(); + Log.d(Constants.TAG, "isAllowed packageName: " + packageName); byte[] packageSignature; try { @@ -80,8 +78,9 @@ public abstract class RemoteService extends Service { intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_REGISTER, intent, 0); + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, + intent, + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); // return PendingIntent to be executed by client Intent result = new Intent(); @@ -99,8 +98,9 @@ public abstract class RemoteService extends Service { getString(R.string.api_error_wrong_signature)); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_ERROR, intent, 0); + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, + intent, + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); // return PendingIntent to be executed by client Intent result = new Intent(); @@ -163,8 +163,9 @@ public abstract class RemoteService extends Service { intent.putExtra(RemoteServiceActivity.EXTRA_ACC_NAME, accountName); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); - PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_REGISTER, intent, 0); + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, + intent, + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); // return PendingIntent to be executed by client Intent result = new Intent(); @@ -206,7 +207,7 @@ public abstract class RemoteService extends Service { } } - Log.d(Constants.TAG, "Caller is NOT allowed!"); + Log.d(Constants.TAG, "Uid is NOT allowed!"); return false; } @@ -218,7 +219,7 @@ public abstract class RemoteService extends Service { * @throws WrongPackageSignatureException */ private boolean isPackageAllowed(String packageName) throws WrongPackageSignatureException { - Log.d(Constants.TAG, "packageName: " + packageName); + Log.d(Constants.TAG, "isPackageAllowed packageName: " + packageName); ArrayList allowedPkgs = ProviderHelper.getRegisteredApiApps(this); Log.d(Constants.TAG, "allowed: " + allowedPkgs); @@ -246,6 +247,7 @@ public abstract class RemoteService extends Service { } } + Log.d(Constants.TAG, "Package is NOT allowed! packageName: " + packageName); return false; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java index 5a6151d88..a6db02708 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java @@ -55,20 +55,7 @@ public class AppSettingsFragment extends Fragment { public void setAppSettings(AppSettings appSettings) { this.mAppSettings = appSettings; - setPackage(appSettings.getPackageName()); - mPackageName.setText(appSettings.getPackageName()); - - try { - MessageDigest md = MessageDigest.getInstance("SHA-256"); - md.update(appSettings.getPackageSignature()); - byte[] digest = md.digest(); - String signature = new String(Hex.encode(digest)); - - mPackageSignature.setText(signature); - } catch (NoSuchAlgorithmException e) { - Log.e(Constants.TAG, "Should not happen!", e); - } - + updateView(appSettings); } /** @@ -77,36 +64,44 @@ public class AppSettingsFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.api_app_settings_fragment, container, false); - initView(view); - return view; - } - - - private void initView(View view) { mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name); mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon); - mPackageName = (TextView) view.findViewById(R.id.api_app_settings_package_name); mPackageSignature = (TextView) view.findViewById(R.id.api_app_settings_package_signature); + return view; } - private void setPackage(String packageName) { - PackageManager pm = getActivity().getApplicationContext().getPackageManager(); - + private void updateView(AppSettings appSettings) { // get application name and icon from package manager String appName; Drawable appIcon = null; + PackageManager pm = getActivity().getApplicationContext().getPackageManager(); try { - ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); + ApplicationInfo ai = pm.getApplicationInfo(appSettings.getPackageName(), 0); appName = (String) pm.getApplicationLabel(ai); appIcon = pm.getApplicationIcon(ai); } catch (NameNotFoundException e) { // fallback - appName = packageName; + appName = appSettings.getPackageName(); } mAppNameView.setText(appName); mAppIconView.setImageDrawable(appIcon); + + // advanced info: package name + mPackageName.setText(appSettings.getPackageName()); + + // advanced info: package signature SHA-256 + try { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + md.update(appSettings.getPackageSignature()); + byte[] digest = md.digest(); + String signature = new String(Hex.encode(digest)); + + mPackageSignature.setText(signature); + } catch (NoSuchAlgorithmException e) { + Log.e(Constants.TAG, "Should not happen!", e); + } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java index d3ac5cade..ba0d4d088 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java @@ -95,6 +95,7 @@ public class RemoteServiceActivity extends ActionBarActivity { if (ACTION_REGISTER.equals(action)) { final String packageName = extras.getString(EXTRA_PACKAGE_NAME); final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE); + Log.d(Constants.TAG, "ACTION_REGISTER packageName: "+packageName); // Inflate a "Done"/"Cancel" custom action bar view ActionBarHelper.setTwoButtonView(getSupportActionBar(), -- cgit v1.2.3 From 65857d2b5fea5cbb5d156b1b4ddfd68ded311624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 26 Mar 2014 17:43:26 +0100 Subject: Accounts list prettified --- .../keychain/remote/ui/AccountsListFragment.java | 27 ++++++++++++++++++++++ .../keychain/remote/ui/AppSettingsActivity.java | 1 - 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java index 22ee7db76..8e65a2f04 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java @@ -32,11 +32,15 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; +import android.widget.LinearLayout; +import android.widget.ListView; import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.ui.widget.FixedListView; import org.sufficientlysecure.keychain.util.Log; public class AccountsListFragment extends ListFragment implements @@ -63,6 +67,29 @@ public class AccountsListFragment extends ListFragment implements return frag; } + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View layout = super.onCreateView(inflater, container, + savedInstanceState); + ListView lv = (ListView) layout.findViewById(android.R.id.list); + ViewGroup parent = (ViewGroup) lv.getParent(); + + /* + * http://stackoverflow.com/a/15880684 + * Remove ListView and add FixedListView in its place. + * This is done here programatically to be still able to use the progressBar of ListFragment. + * + * We want FixedListView to be able to put this ListFragment inside a ScrollView + */ + int lvIndex = parent.indexOfChild(lv); + parent.removeViewAt(lvIndex); + FixedListView newLv = new FixedListView(getActivity()); + newLv.setId(android.R.id.list); + parent.addView(newLv, lvIndex, lv.getLayoutParams()); + return layout; + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java index e4b943734..9e0ba49eb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java @@ -103,7 +103,6 @@ public class AppSettingsActivity extends ActionBarActivity { } setTitle(appName); - Uri accountsUri = appUri.buildUpon().appendPath(KeychainContract.PATH_ACCOUNTS).build(); Log.d(Constants.TAG, "accountsUri: " + accountsUri); startListFragment(savedInstanceState, accountsUri); -- cgit v1.2.3 From 2e063a42ed9a0d2976b52b8bc40a12672f3ae166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 26 Mar 2014 17:55:48 +0100 Subject: Fix provider for API_ACCOUNTS --- .../keychain/provider/KeychainContract.java | 2 +- .../keychain/provider/KeychainDatabase.java | 6 +++--- .../keychain/provider/KeychainProvider.java | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index 6e4899fc2..e7b31bf65 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -65,7 +65,7 @@ public class KeychainContract { String ENCRYPTION_ALGORITHM = "encryption_algorithm"; String HASH_ALORITHM = "hash_algorithm"; String COMPRESSION = "compression"; - String PACKAGE_NAME_FK = "package_name"; // foreign key to api_apps.package_name + String PACKAGE_NAME = "package_name"; // foreign key to api_apps.package_name } public static final class KeyTypes { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 4abcec435..8c33844b2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -88,10 +88,10 @@ public class KeychainDatabase extends SQLiteOpenHelper { + ApiAppsAccountsColumns.ENCRYPTION_ALGORITHM + " INTEGER, " + ApiAppsAccountsColumns.HASH_ALORITHM + " INTEGER, " + ApiAppsAccountsColumns.COMPRESSION + " INTEGER, " - + ApiAppsAccountsColumns.PACKAGE_NAME_FK + " TEXT NOT NULL, " + + ApiAppsAccountsColumns.PACKAGE_NAME + " TEXT NOT NULL, " + "UNIQUE(" + ApiAppsAccountsColumns.ACCOUNT_NAME + ", " - + ApiAppsAccountsColumns.PACKAGE_NAME_FK + "), " - + "FOREIGN KEY(" + ApiAppsAccountsColumns.PACKAGE_NAME_FK + ") REFERENCES " + + ApiAppsAccountsColumns.PACKAGE_NAME + "), " + + "FOREIGN KEY(" + ApiAppsAccountsColumns.PACKAGE_NAME + ") REFERENCES " + Tables.API_APPS + "(" + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE)"; KeychainDatabase(Context context) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 6469da978..1c5e3ab36 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -687,13 +687,13 @@ public class KeychainProvider extends ContentProvider { break; case API_ACCOUNTS: qb.setTables(Tables.API_ACCOUNTS); + qb.appendWhere(Tables.API_ACCOUNTS + "." + ApiAccounts.PACKAGE_NAME + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(1)); break; case API_ACCOUNTS_BY_ACCOUNT_NAME: - qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "(" - + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "." - + ApiAccounts.PACKAGE_NAME_FK + " )"); - qb.appendWhere(Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = "); + qb.setTables(Tables.API_ACCOUNTS); + qb.appendWhere(Tables.API_ACCOUNTS + "." + ApiAccounts.PACKAGE_NAME + " = "); qb.appendWhereEscapeString(uri.getPathSegments().get(1)); qb.appendWhere(" AND " + Tables.API_ACCOUNTS + "." + ApiAccounts.ACCOUNT_NAME + " = "); @@ -800,7 +800,7 @@ public class KeychainProvider extends ContentProvider { // set foreign key automatically based on given uri // e.g., api_apps/com.example.app/accounts/ String packageName = uri.getPathSegments().get(1); - values.put(ApiAccounts.PACKAGE_NAME_FK, packageName); + values.put(ApiAccounts.PACKAGE_NAME, packageName); Log.d(Constants.TAG, "provider packageName: " + packageName); @@ -1061,7 +1061,7 @@ public class KeychainProvider extends ContentProvider { andSelection = " AND (" + selection + ")"; } - return ApiAccounts.PACKAGE_NAME_FK + "=" + packageName + " AND " + return ApiAccounts.PACKAGE_NAME + "=" + packageName + " AND " + ApiAccounts.ACCOUNT_NAME + "=" + accountName + andSelection; } -- cgit v1.2.3 From 399106015e6d4a8d08385f9d5d360fe634e5cc56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 26 Mar 2014 18:18:00 +0100 Subject: Rename layouts for remote activity --- .../keychain/remote/ui/RemoteServiceActivity.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java index ba0d4d088..a894da448 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java @@ -124,7 +124,7 @@ public class RemoteServiceActivity extends ActionBarActivity { } ); - setContentView(R.layout.api_app_register_activity); + setContentView(R.layout.api_remote_register_app); mAppSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( R.id.api_app_settings_fragment); @@ -169,7 +169,7 @@ public class RemoteServiceActivity extends ActionBarActivity { } ); - setContentView(R.layout.api_account_create_activity); + setContentView(R.layout.api_remote_create_account); mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById( R.id.api_account_settings_fragment); @@ -235,7 +235,7 @@ public class RemoteServiceActivity extends ActionBarActivity { } ); - setContentView(R.layout.api_app_select_pub_keys_activity); + setContentView(R.layout.api_remote_select_pub_keys); // set text on view HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_select_pub_keys_text); @@ -277,7 +277,7 @@ public class RemoteServiceActivity extends ActionBarActivity { } }); - setContentView(R.layout.api_app_error_message); + setContentView(R.layout.api_remote_error_message); // set text on view HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_app_error_message_text); -- cgit v1.2.3 From cc8fd35137d1c8e78727a76a5cceb5f92b234a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 26 Mar 2014 18:34:48 +0100 Subject: Show divider only when used --- .../java/org/sufficientlysecure/keychain/ui/KeyListFragment.java | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index daf455c03..957c822d2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -498,11 +498,15 @@ public class KeyListFragment extends Fragment } { // set edit button and revoked info, specific by key type + View statusDivider = (View) view.findViewById(R.id.status_divider); + FrameLayout statusLayout = (FrameLayout) view.findViewById(R.id.status_layout); Button button = (Button) view.findViewById(R.id.edit); TextView revoked = (TextView) view.findViewById(R.id.revoked); if (cursor.getInt(KeyListFragment.INDEX_TYPE) == KeyTypes.SECRET) { // this is a secret key - show the edit button + statusDivider.setVisibility(View.VISIBLE); + statusLayout.setVisibility(View.VISIBLE); revoked.setVisibility(View.GONE); button.setVisibility(View.VISIBLE); @@ -519,9 +523,11 @@ public class KeyListFragment extends Fragment }); } else { // this is a public key - hide the edit button, show if it's revoked + statusDivider.setVisibility(View.GONE); button.setVisibility(View.GONE); boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0; + statusLayout.setVisibility(isRevoked ? View.VISIBLE : View.GONE); revoked.setVisibility(isRevoked ? View.VISIBLE : View.GONE); } } -- cgit v1.2.3 From 140646fa121958ba3b19decd8a92f470fe13ac43 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 27 Mar 2014 13:35:03 +0000 Subject: pass through original primary ID --- .../sufficientlysecure/keychain/ui/EditKeyActivity.java | 1 + .../keychain/ui/widget/SectionView.java | 15 +++++++++++++++ .../keychain/ui/widget/UserIdEditor.java | 5 +++++ 3 files changed, 21 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 716140655..0726897c3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -597,6 +597,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener saveParams.oldPassPhrase = mCurrentPassphrase; saveParams.newKeys = toPrimitiveArray(mKeysView.getNewKeysArray()); saveParams.keys = getKeys(mKeysView); + saveParams.originalPrimaryID = mUserIdsView.getOriginalPrimaryID(); // fill values for this action diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 6ab422d69..9758835d2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -198,6 +198,21 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor return ret; } + public String getOriginalPrimaryID() + { //NB: this will have to change when we change how Primary IDs are chosen, and so we need to be + // careful about where Master key capabilities are stored... multiple primaries and + // revoked ones make this harder than the simple case we are continuing to assume here + for (int i = 0; i < mEditors.getChildCount(); ++i) { + Editor editor = (Editor) mEditors.getChildAt(i); + if (mType == Id.type.user_id) { + if(((UserIdEditor)editor).getIsOriginallyMainUserID()) { + return ((UserIdEditor)editor).getOriginalID(); + } + } + } + return null; + } + public ArrayList getOriginalIDs() { ArrayList orig = new ArrayList(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index 5098c8713..8760b72f7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -229,6 +229,11 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene return retval; } + public boolean getIsOriginallyMainUserID() + { + return mOriginallyMainUserID; + } + public boolean primarySwapped() { return (mOriginallyMainUserID != isMainUserId()); -- cgit v1.2.3 From 56447ad0b55d2ff41e5acb6b8f8ee85393eee05c Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 27 Mar 2014 14:48:27 +0000 Subject: fix for editing master keys and IDs, case of change primary ID and modify master key props fails --- .../keychain/pgp/PgpKeyOperation.java | 32 ++++++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 9bf9ecc73..603b8dcd1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -440,12 +440,12 @@ public class PgpKeyOperation { //this happens anyway } - if (saveParcel.primaryIDChanged) { + if (saveParcel.primaryIDChanged || !saveParcel.originalIDs.get(0).equals(saveParcel.userIDs.get(0))) { anyIDChanged = true; ArrayList> sigList = new ArrayList>(); for (String userId : saveParcel.userIDs) { String orig_id = saveParcel.originalIDs.get(user_id_index); - if (orig_id.equals(userId)) { + if (orig_id.equals(userId) && !userId.equals(saveParcel.originalPrimaryID) && user_id_index != 0) { Iterator orig_sigs = masterPublicKey.getSignaturesForID(orig_id); //TODO: make sure this iterator only has signatures we are interested in while (orig_sigs.hasNext()) { PGPSignature orig_sig = orig_sigs.next(); @@ -498,8 +498,23 @@ public class PgpKeyOperation { } } + ArrayList> sigList = new ArrayList>(); if (saveParcel.moddedKeys[0]) { - masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, saveParcel.originalIDs.get(0)); + user_id_index = 0; + for (String userId : saveParcel.userIDs) { + String orig_id = saveParcel.originalIDs.get(user_id_index); + if (!orig_id.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged) { + Iterator sigs = masterPublicKey.getSignaturesForID(userId); //TODO: make sure this iterator only has signatures we are interested in + while (sigs.hasNext()) { + PGPSignature sig = sigs.next(); + sigList.add(new Pair(userId, sig)); + } + } + if (!userId.equals("")) { + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, userId); + } + user_id_index++; + } anyIDChanged = true; } @@ -606,6 +621,17 @@ public class PgpKeyOperation { pKR = PGPPublicKeyRing.insertPublicKey(pKR, theNextKey.getPublicKey()); } } + + //replace lost IDs + if (saveParcel.moddedKeys[0]) { + masterPublicKey = mKR.getPublicKey(); + for (Pair to_add : sigList) { + masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, to_add.first, to_add.second); + } + pKR = PGPPublicKeyRing.insertPublicKey(pKR, masterPublicKey); + mKR = PGPSecretKeyRing.replacePublicKeys(mKR, pKR); + } + // Build key encryptor based on new passphrase PBESecretKeyEncryptor keyEncryptorNew = new JcePBESecretKeyEncryptorBuilder( PGPEncryptedData.CAST5, sha1Calc) -- cgit v1.2.3 From 7a2d880c4db21ab62cb152f10d1938a36319acb3 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Thu, 27 Mar 2014 15:00:35 +0000 Subject: all editing cases I can think of now work --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 603b8dcd1..b7f84ccdc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -503,7 +503,7 @@ public class PgpKeyOperation { user_id_index = 0; for (String userId : saveParcel.userIDs) { String orig_id = saveParcel.originalIDs.get(user_id_index); - if (!orig_id.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged) { + if (!(orig_id.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged)) { Iterator sigs = masterPublicKey.getSignaturesForID(userId); //TODO: make sure this iterator only has signatures we are interested in while (sigs.hasNext()) { PGPSignature sig = sigs.next(); -- cgit v1.2.3 From d5e3958565054dff06bd02d3c3391935e7c2a961 Mon Sep 17 00:00:00 2001 From: Miroojin Bakshi Date: Fri, 28 Mar 2014 00:34:24 +0530 Subject: Enable importing of fingerprints from clipboard. --- .../keychain/ui/ImportKeysClipboardFragment.java | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java index 3f0b4a46e..e53762580 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java @@ -17,6 +17,7 @@ package org.sufficientlysecure.keychain.ui; +import android.net.Uri; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; @@ -24,9 +25,13 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import com.beardedhen.androidbootstrap.BootstrapButton; + +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; +import java.util.Locale; + public class ImportKeysClipboardFragment extends Fragment { private ImportKeysActivity mImportActivity; @@ -60,6 +65,10 @@ public class ImportKeysClipboardFragment extends Fragment { String sendText = ""; if (clipboardText != null) { sendText = clipboardText.toString(); + if(sendText.toLowerCase(Locale.ENGLISH).startsWith(Constants.FINGERPRINT_SCHEME)) { + mImportActivity.loadFromFingerprintUri(null, Uri.parse(sendText)); + return; + } } mImportActivity.loadCallback(sendText.getBytes(), null, null, null); } -- cgit v1.2.3 From 556d6ff2268c8769d2d9d16eb0a50c8b0ee97365 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sat, 29 Mar 2014 15:19:38 +0000 Subject: revert mistake --- .../java/org/sufficientlysecure/keychain/provider/ProviderHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index b47c4946f..b971143ae 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -354,7 +354,7 @@ public class ProviderHelper { values.put(Keys.KEY_SIZE, key.getPublicKey().getBitStrength()); values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key) && hasPrivate)); values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key) && hasPrivate)); - values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key) && hasPrivate); + values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key)); values.put(Keys.IS_REVOKED, key.getPublicKey().isRevoked()); values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000); Date expiryDate = PgpKeyHelper.getExpiryDate(key); -- cgit v1.2.3 From b2342744b5f8e5bce62db18f93468fc0781a2c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 30 Mar 2014 14:02:09 +0200 Subject: Actually use fixBadCharactersForGmail --- .../main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 4f18f69d7..cc8224f06 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -579,7 +579,7 @@ public class EncryptActivity extends DrawerActivity { String message = mMessage.getText().toString(); if (signOnly) { - fixBadCharactersForGmail(message); + message = fixBadCharactersForGmail(message); } data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, message.getBytes()); } -- cgit v1.2.3 From be007ecc56809cc0b6d489ab09be656e2ced9c32 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Sun, 30 Mar 2014 16:22:13 +0100 Subject: style changes --- .../keychain/pgp/PgpKeyOperation.java | 53 +++++++++++----------- 1 file changed, 26 insertions(+), 27 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 05ca99578..592bdec73 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -217,7 +217,7 @@ public class PgpKeyOperation { PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor); updateProgress(R.string.progress_certifying_master_key, 20, 100); - int user_id_index = 0; + for (String userId : userIds) { PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) @@ -228,7 +228,6 @@ public class PgpKeyOperation { PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); - user_id_index++; } PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey); @@ -412,7 +411,7 @@ public class PgpKeyOperation { masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, delID); } - int user_id_index = 0; + int userIDIndex = 0; PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); @@ -442,12 +441,12 @@ public class PgpKeyOperation { anyIDChanged = true; ArrayList> sigList = new ArrayList>(); for (String userId : saveParcel.userIDs) { - String orig_id = saveParcel.originalIDs.get(user_id_index); - if (orig_id.equals(userId) && !userId.equals(saveParcel.originalPrimaryID) && user_id_index != 0) { - Iterator orig_sigs = masterPublicKey.getSignaturesForID(orig_id); //TODO: make sure this iterator only has signatures we are interested in - while (orig_sigs.hasNext()) { - PGPSignature orig_sig = orig_sigs.next(); - sigList.add(new Pair(orig_id, orig_sig)); + String origID = saveParcel.originalIDs.get(userIDIndex); + if (origID.equals(userId) && !userId.equals(saveParcel.originalPrimaryID) && userIDIndex != 0) { + Iterator origSigs = masterPublicKey.getSignaturesForID(origID); //TODO: make sure this iterator only has signatures we are interested in + while (origSigs.hasNext()) { + PGPSignature origSig = origSigs.next(); + sigList.add(new Pair(origID, origSig)); } } else { PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( @@ -456,25 +455,25 @@ public class PgpKeyOperation { PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); - if (user_id_index == 0) { + if (userIDIndex == 0) { sGen.setHashedSubpackets(hashedPacketsGen.generate()); sGen.setUnhashedSubpackets(unhashedPacketsGen.generate()); } PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); sigList.add(new Pair(userId, certification)); } - if (!orig_id.equals("")) { - masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, orig_id); + if (!origID.equals("")) { + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID); } - user_id_index++; + userIDIndex++; } - for (Pair to_add : sigList) { - masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, to_add.first, to_add.second); + for (Pair toAdd : sigList) { + masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, toAdd.first, toAdd.second); } } else { for (String userId : saveParcel.userIDs) { - String orig_id = saveParcel.originalIDs.get(user_id_index); - if (!orig_id.equals(userId)) { + String origID = saveParcel.originalIDs.get(userIDIndex); + if (!origID.equals(userId)) { anyIDChanged = true; PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) @@ -482,26 +481,26 @@ public class PgpKeyOperation { PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); - if (user_id_index == 0) { + if (userIDIndex == 0) { sGen.setHashedSubpackets(hashedPacketsGen.generate()); sGen.setUnhashedSubpackets(unhashedPacketsGen.generate()); } PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); - if (!orig_id.equals("")) { - masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, orig_id); + if (!origID.equals("")) { + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID); } masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); } - user_id_index++; + userIDIndex++; } } ArrayList> sigList = new ArrayList>(); if (saveParcel.moddedKeys[0]) { - user_id_index = 0; + userIDIndex = 0; for (String userId : saveParcel.userIDs) { - String orig_id = saveParcel.originalIDs.get(user_id_index); - if (!(orig_id.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged)) { + String origID = saveParcel.originalIDs.get(userIDIndex); + if (!(origID.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged)) { Iterator sigs = masterPublicKey.getSignaturesForID(userId); //TODO: make sure this iterator only has signatures we are interested in while (sigs.hasNext()) { PGPSignature sig = sigs.next(); @@ -511,7 +510,7 @@ public class PgpKeyOperation { if (!userId.equals("")) { masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, userId); } - user_id_index++; + userIDIndex++; } anyIDChanged = true; } @@ -623,8 +622,8 @@ public class PgpKeyOperation { //replace lost IDs if (saveParcel.moddedKeys[0]) { masterPublicKey = mKR.getPublicKey(); - for (Pair to_add : sigList) { - masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, to_add.first, to_add.second); + for (Pair toAdd : sigList) { + masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, toAdd.first, toAdd.second); } pKR = PGPPublicKeyRing.insertPublicKey(pKR, masterPublicKey); mKR = PGPSecretKeyRing.replacePublicKeys(mKR, pKR); -- cgit v1.2.3 From 7b53150ad55f732c6bf01e0d0fd2bea624068182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 30 Mar 2014 19:25:39 +0200 Subject: Remove FLAG_ONE_SHOT from most PIs --- .../org/sufficientlysecure/keychain/remote/OpenPgpService.java | 8 ++++---- .../org/sufficientlysecure/keychain/remote/RemoteService.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index ad0c658ad..f85e342d8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -99,7 +99,7 @@ public class OpenPgpService extends RemoteService { PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, intent, - PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); + PendingIntent.FLAG_CANCEL_CURRENT); // return PendingIntent to be executed by client Intent result = new Intent(); @@ -127,7 +127,7 @@ public class OpenPgpService extends RemoteService { intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, intent, - PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); + PendingIntent.FLAG_CANCEL_CURRENT); // return PendingIntent to be executed by client Intent result = new Intent(); @@ -319,7 +319,7 @@ public class OpenPgpService extends RemoteService { PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, intent, - PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); + PendingIntent.FLAG_CANCEL_CURRENT); result.putExtra(OpenPgpApi.RESULT_INTENT, pi); } @@ -360,7 +360,7 @@ public class OpenPgpService extends RemoteService { PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, intent, - PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); + PendingIntent.FLAG_CANCEL_CURRENT); result.putExtra(OpenPgpApi.RESULT_INTENT, pi); result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java index 8cea3cd21..59a04a10e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java @@ -100,7 +100,7 @@ public abstract class RemoteService extends Service { PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, intent, - PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); + PendingIntent.FLAG_CANCEL_CURRENT); // return PendingIntent to be executed by client Intent result = new Intent(); @@ -165,7 +165,7 @@ public abstract class RemoteService extends Service { PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, intent, - PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); + PendingIntent.FLAG_CANCEL_CURRENT); // return PendingIntent to be executed by client Intent result = new Intent(); -- cgit v1.2.3 From 3c0b97f280f11d553d93df9bc93ce47098af35d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 30 Mar 2014 19:26:41 +0200 Subject: Remove cancel from app menu --- .../sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java | 3 --- 1 file changed, 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java index 671a3e0aa..d1c049e2a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java @@ -82,9 +82,6 @@ public class AccountSettingsActivity extends ActionBarActivity { case R.id.menu_account_settings_delete: deleteAccount(); return true; - case R.id.menu_account_settings_cancel: - finish(); - return true; } return super.onOptionsItemSelected(item); } -- cgit v1.2.3 From 583467356c5abea80be673264b3f600c578a862d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 30 Mar 2014 19:28:35 +0200 Subject: Revert "Remove cancel from app menu" This reverts commit 3c0b97f280f11d553d93df9bc93ce47098af35d4. --- .../sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java index d1c049e2a..671a3e0aa 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java @@ -82,6 +82,9 @@ public class AccountSettingsActivity extends ActionBarActivity { case R.id.menu_account_settings_delete: deleteAccount(); return true; + case R.id.menu_account_settings_cancel: + finish(); + return true; } return super.onOptionsItemSelected(item); } -- cgit v1.2.3 From 224e8a7554a58f98b6ff71cc1a15d14108f98242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 30 Mar 2014 19:29:07 +0200 Subject: Remove cancel from app menu --- .../org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java | 3 --- 1 file changed, 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java index 9e0ba49eb..f6f9631cb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java @@ -80,9 +80,6 @@ public class AppSettingsActivity extends ActionBarActivity { case R.id.menu_api_settings_revoke: revokeAccess(); return true; - case R.id.menu_api_settings_cancel: - finish(); - return true; } return super.onOptionsItemSelected(item); } -- cgit v1.2.3 From 4cec2194e01b7213271fa1fb0d50e5ae386fb16e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 29 Mar 2014 00:11:07 +0100 Subject: Experiments with fragments in decrypt activity --- .../keychain/ui/DecryptActivity.java | 350 ++++++++++++--------- .../keychain/ui/DecryptFileFragment.java | 62 ++++ .../keychain/ui/DecryptMessageFragment.java | 78 +++++ .../keychain/ui/adapter/PageTabStripAdapter.java | 74 +++++ .../keychain/ui/adapter/TabsAdapter.java | 12 +- 5 files changed, 421 insertions(+), 155 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PageTabStripAdapter.java (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 9b3b00c19..24a8854af 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -25,12 +25,17 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Messenger; +import android.support.v4.app.Fragment; +import android.support.v4.view.PagerTabStrip; +import android.support.v4.view.ViewPager; import android.view.View; import android.view.View.OnClickListener; import android.view.animation.AnimationUtils; import android.widget.*; + import com.beardedhen.androidbootstrap.BootstrapButton; import com.devspark.appmsg.AppMsg; + import org.openintents.openpgp.OpenPgpSignatureResult; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.sufficientlysecure.keychain.Constants; @@ -49,6 +54,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.PassphraseCacheService; +import org.sufficientlysecure.keychain.ui.adapter.PageTabStripAdapter; import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; @@ -57,7 +63,7 @@ import org.sufficientlysecure.keychain.util.Log; import java.io.*; import java.util.regex.Matcher; -@SuppressLint("NewApi") +//@SuppressLint("NewApi") public class DecryptActivity extends DrawerActivity { /* Intents */ @@ -67,28 +73,30 @@ public class DecryptActivity extends DrawerActivity { /* EXTRA keys for input */ public static final String EXTRA_TEXT = "text"; + public static final String EXTRA_SELECTED_TAB = "selected_tab"; + private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006; private static final int RESULT_CODE_FILE = 0x00007003; private long mSignatureKeyId = 0; - private boolean mReturnResult = false; +// private boolean mReturnResult = false; // TODO: replace signed only checks with something more intelligent // PgpDecryptVerify should handle all automatically!!! private boolean mSignedOnly = false; private boolean mAssumeSymmetricEncryption = false; - private EditText mMessage = null; + // private EditText mMessage = null; private RelativeLayout mSignatureLayout = null; private ImageView mSignatureStatusImage = null; private TextView mUserId = null; private TextView mUserIdRest = null; - private ViewFlipper mSource = null; - private TextView mSourceLabel = null; - private ImageView mSourcePrevious = null; - private ImageView mSourceNext = null; +// private ViewFlipper mSource = null; +// private TextView mSourceLabel = null; +// private ImageView mSourcePrevious = null; +// private ImageView mSourceNext = null; private int mDecryptTarget; @@ -107,45 +115,50 @@ public class DecryptActivity extends DrawerActivity { private FileDialogFragment mFileDialog; - private boolean mDecryptImmediately = false; +// private boolean mDecryptImmediately = false; private BootstrapButton mDecryptButton; - private void initView() { - mSource = (ViewFlipper) findViewById(R.id.source); - mSourceLabel = (TextView) findViewById(R.id.sourceLabel); - mSourcePrevious = (ImageView) findViewById(R.id.sourcePrevious); - mSourceNext = (ImageView) findViewById(R.id.sourceNext); - - mSourcePrevious.setClickable(true); - mSourcePrevious.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - mSource.setInAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, - R.anim.push_right_in)); - mSource.setOutAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, - R.anim.push_right_out)); - mSource.showPrevious(); - updateSource(); - } - }); - - mSourceNext.setClickable(true); - OnClickListener nextSourceClickListener = new OnClickListener() { - public void onClick(View v) { - mSource.setInAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, - R.anim.push_left_in)); - mSource.setOutAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, - R.anim.push_left_out)); - mSource.showNext(); - updateSource(); - } - }; - mSourceNext.setOnClickListener(nextSourceClickListener); + ViewPager mViewPager; + PagerTabStrip mPagerTabStrip; + PageTabStripAdapter mTabsAdapter; + DecryptMessageFragment mMessageFragment; + DecryptFileFragment mFileFragment; - mSourceLabel.setClickable(true); - mSourceLabel.setOnClickListener(nextSourceClickListener); + private void initView() { +// mSource = (ViewFlipper) findViewById(R.id.source); +// mSourceLabel = (TextView) findViewById(R.id.sourceLabel); +// mSourcePrevious = (ImageView) findViewById(R.id.sourcePrevious); +// mSourceNext = (ImageView) findViewById(R.id.sourceNext); +// +// mSourcePrevious.setClickable(true); +// mSourcePrevious.setOnClickListener(new OnClickListener() { +// public void onClick(View v) { +// mSource.setInAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, +// R.anim.push_right_in)); +// mSource.setOutAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, +// R.anim.push_right_out)); +// mSource.showPrevious(); +// updateSource(); +// } +// }); +// +// mSourceNext.setClickable(true); +// OnClickListener nextSourceClickListener = new OnClickListener() { +// public void onClick(View v) { +// mSource.setInAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, +// R.anim.push_left_in)); +// mSource.setOutAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, +// R.anim.push_left_out)); +// mSource.showNext(); +// updateSource(); +// } +// }; +// mSourceNext.setOnClickListener(nextSourceClickListener); +// +// mSourceLabel.setClickable(true); +// mSourceLabel.setOnClickListener(nextSourceClickListener); - mMessage = (EditText) findViewById(R.id.message); mSignatureLayout = (RelativeLayout) findViewById(R.id.signature); mSignatureStatusImage = (ImageView) findViewById(R.id.ic_signature_status); mUserId = (TextView) findViewById(R.id.mainUserId); @@ -153,10 +166,10 @@ public class DecryptActivity extends DrawerActivity { // measure the height of the source_file view and set the message view's min height to that, // so it fills mSource fully... bit of a hack. - View tmp = findViewById(R.id.sourceFile); - tmp.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - int height = tmp.getMeasuredHeight(); - mMessage.setMinimumHeight(height); +// View tmp = findViewById(R.id.sourceFile); +// tmp.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); +// int height = tmp.getMeasuredHeight(); +// mMessage.setMinimumHeight(height); mFilename = (EditText) findViewById(R.id.filename); mBrowse = (BootstrapButton) findViewById(R.id.btn_browse); @@ -178,11 +191,11 @@ public class DecryptActivity extends DrawerActivity { mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterDecryption); // default: message source - mSource.setInAnimation(null); - mSource.setOutAnimation(null); - while (mSource.getCurrentView().getId() != R.id.sourceMessage) { - mSource.showNext(); - } +// mSource.setInAnimation(null); +// mSource.setOutAnimation(null); +// while (mSource.getCurrentView().getId() != R.id.sourceMessage) { +// mSource.showNext(); +// } mDecryptButton = (BootstrapButton) findViewById(R.id.action_decrypt); mDecryptButton.setOnClickListener(new OnClickListener() { @@ -191,6 +204,49 @@ public class DecryptActivity extends DrawerActivity { decryptClicked(); } }); + + mViewPager = (ViewPager) findViewById(R.id.decrypt_pager); + mPagerTabStrip = (PagerTabStrip) findViewById(R.id.decrypt_pager_tab_strip); + initPager(); + } + + private static final int PAGER_TAB_MESSAGE = 0; + private static final int PAGER_TAB_FILE = 1; + + private void initPager() { + mTabsAdapter = new PageTabStripAdapter(this); + mViewPager.setAdapter(mTabsAdapter); + + Bundle messageBundle = new Bundle(); + mTabsAdapter.addTab(DecryptMessageFragment.class, messageBundle, getString(R.string.label_message)); + + Bundle fileBundle = new Bundle(); + mTabsAdapter.addTab(DecryptFileFragment.class, fileBundle, getString(R.string.label_file)); + +// mPagerTabStrip. + getSupportFragmentManager().executePendingTransactions(); +// for (Fragment f : getSupportFragmentManager().getFragments()) { +// Log.d(Constants.TAG, "f: "+f.getTag()); +// } + + DecryptMessageFragment messageFragment = (DecryptMessageFragment) getFragmentByPosition(PAGER_TAB_MESSAGE); +// mFileFragment = (DecryptFileFragment) getFragmentByPosition(PAGER_TAB_FILE); + +// Log.d(Constants.TAG, fr.getTag()); +// + } + + /** + * find fragment + * + * @param pos + * @return + */ + public Fragment getFragmentByPosition(int pos) { + // based on FragmentPagerAdapter.makeFragmentName() + String tag = "android:switcher:" + mViewPager.getId() + ":" + pos; + Log.d(Constants.TAG, "findFragmentByTag: "+tag); + return getSupportFragmentManager().findFragmentByTag(tag); } @Override @@ -209,25 +265,25 @@ public class DecryptActivity extends DrawerActivity { // Handle intent actions handleActions(getIntent()); - if (mSource.getCurrentView().getId() == R.id.sourceMessage - && mMessage.getText().length() == 0) { - - CharSequence clipboardText = ClipboardReflection.getClipboardText(this); - - String data = ""; - if (clipboardText != null) { - Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText); - if (!matcher.matches()) { - matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(clipboardText); - } - if (matcher.matches()) { - data = matcher.group(1); - mMessage.setText(data); - AppMsg.makeText(this, R.string.using_clipboard_content, AppMsg.STYLE_INFO) - .show(); - } - } - } +// if (mSource.getCurrentView().getId() == R.id.sourceMessage +// && mMessage.getText().length() == 0) { +// +// CharSequence clipboardText = ClipboardReflection.getClipboardText(this); +// +// String data = ""; +// if (clipboardText != null) { +// Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText); +// if (!matcher.matches()) { +// matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(clipboardText); +// } +// if (matcher.matches()) { +// data = matcher.group(1); +// mMessage.setText(data); +// AppMsg.makeText(this, R.string.using_clipboard_content, AppMsg.STYLE_INFO) +// .show(); +// } +// } +// } mSignatureLayout.setVisibility(View.GONE); mSignatureLayout.setOnClickListener(new OnClickListener() { @@ -246,28 +302,29 @@ public class DecryptActivity extends DrawerActivity { } }); - if (mReturnResult) { - mSourcePrevious.setClickable(false); - mSourcePrevious.setEnabled(false); - mSourcePrevious.setVisibility(View.INVISIBLE); - - mSourceNext.setClickable(false); - mSourceNext.setEnabled(false); - mSourceNext.setVisibility(View.INVISIBLE); - - mSourceLabel.setClickable(false); - mSourceLabel.setEnabled(false); - } - - updateSource(); - - if (mDecryptImmediately - || (mSource.getCurrentView().getId() == R.id.sourceMessage && (mMessage.getText() - .length() > 0 || mContentUri != null))) { - decryptClicked(); - } +// if (mReturnResult) { +// mSourcePrevious.setClickable(false); +// mSourcePrevious.setEnabled(false); +// mSourcePrevious.setVisibility(View.INVISIBLE); +// +// mSourceNext.setClickable(false); +// mSourceNext.setEnabled(false); +// mSourceNext.setVisibility(View.INVISIBLE); +// +// mSourceLabel.setClickable(false); +// mSourceLabel.setEnabled(false); +// } +// +// updateSource(); + +// if (mDecryptImmediately +// || (mSource.getCurrentView().getId() == R.id.sourceMessage && (mMessage.getText() +// .length() > 0 || mContentUri != null))) { +// decryptClicked(); +// } } + /** * Handles all actions with this intent * @@ -316,14 +373,17 @@ public class DecryptActivity extends DrawerActivity { * Main Actions */ if (ACTION_DECRYPT.equals(action) && textData != null) { - Log.d(Constants.TAG, "textData null, matching text ..."); + Log.d(Constants.TAG, "textData not null, matching text ..."); Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(textData); if (matcher.matches()) { Log.d(Constants.TAG, "PGP_MESSAGE matched"); textData = matcher.group(1); // replace non breakable spaces textData = textData.replaceAll("\\xa0", " "); - mMessage.setText(textData); + + mViewPager.setCurrentItem(PAGER_TAB_MESSAGE, false); + mMessageFragment.setText(textData); +// mMessage.setText(textData); } else { matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(textData); if (matcher.matches()) { @@ -331,7 +391,10 @@ public class DecryptActivity extends DrawerActivity { textData = matcher.group(1); // replace non breakable spaces textData = textData.replaceAll("\\xa0", " "); - mMessage.setText(textData); +// mMessage.setText(textData); + mViewPager.setCurrentItem(PAGER_TAB_MESSAGE, false); + mMessageFragment = (DecryptMessageFragment) getFragmentByPosition(mViewPager.getCurrentItem()); + mMessageFragment.setText(textData); } else { Log.d(Constants.TAG, "Nothing matched!"); } @@ -344,14 +407,14 @@ public class DecryptActivity extends DrawerActivity { mInputFilename = path; mFilename.setText(mInputFilename); guessOutputFilename(); - mSource.setInAnimation(null); - mSource.setOutAnimation(null); - while (mSource.getCurrentView().getId() != R.id.sourceFile) { - mSource.showNext(); - } +// mSource.setInAnimation(null); +// mSource.setOutAnimation(null); +// while (mSource.getCurrentView().getId() != R.id.sourceFile) { +// mSource.showNext(); +// } } else { Log.e(Constants.TAG, - "Direct binary data without actual file in filesystem is not supported. Please use the Remote Service API!"); + "Direct binary data without actual file in filesystem is not supported. Please use the Remote Service API!"); Toast.makeText(this, R.string.error_only_files_are_supported, Toast.LENGTH_LONG) .show(); // end activity @@ -373,28 +436,28 @@ public class DecryptActivity extends DrawerActivity { mOutputFilename = Constants.Path.APP_DIR + "/" + filename; } - private void updateSource() { - switch (mSource.getCurrentView().getId()) { - case R.id.sourceFile: { - mSourceLabel.setText(R.string.label_file); - mDecryptButton.setText(getString(R.string.btn_decrypt)); - break; - } - - case R.id.sourceMessage: { - mSourceLabel.setText(R.string.label_message); - mDecryptButton.setText(getString(R.string.btn_decrypt)); - break; - } - - default: { - break; - } - } - } +// private void updateSource() { +// switch (mSource.getCurrentView().getId()) { +// case R.id.sourceFile: { +// mSourceLabel.setText(R.string.label_file); +// mDecryptButton.setText(getString(R.string.btn_decrypt)); +// break; +// } +// +// case R.id.sourceMessage: { +// mSourceLabel.setText(R.string.label_message); +// mDecryptButton.setText(getString(R.string.btn_decrypt)); +// break; +// } +// +// default: { +// break; +// } +// } +// } private void decryptClicked() { - if (mSource.getCurrentView().getId() == R.id.sourceFile) { + if (mViewPager.getCurrentItem() == PAGER_TAB_FILE) { mDecryptTarget = Id.target.file; } else { mDecryptTarget = Id.target.message; @@ -428,13 +491,13 @@ public class DecryptActivity extends DrawerActivity { } if (mDecryptTarget == Id.target.message) { - String messageData = mMessage.getText().toString(); - Matcher matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(messageData); - if (matcher.matches()) { - mSignedOnly = true; - decryptStart(); - return; - } +// String messageData = mMessage.getText().toString(); +// Matcher matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(messageData); +// if (matcher.matches()) { +// mSignedOnly = true; +// decryptStart(); +// return; +// } } // else treat it as an decrypted message/file @@ -519,7 +582,8 @@ public class DecryptActivity extends DrawerActivity { AppMsg.STYLE_ALERT).show(); } } else { - inStream = new ByteArrayInputStream(mMessage.getText().toString().getBytes()); + +// inStream = new ByteArrayInputStream(mMessage.getText().toString().getBytes()); } // get decryption key for this inStream @@ -551,18 +615,6 @@ public class DecryptActivity extends DrawerActivity { } } - private void replyClicked() { - Intent intent = new Intent(this, EncryptActivity.class); - intent.setAction(EncryptActivity.ACTION_ENCRYPT); - String data = mMessage.getText().toString(); - data = data.replaceAll("(?m)^", "> "); - data = "\n\n" + data; - intent.putExtra(EncryptActivity.EXTRA_TEXT, data); - intent.putExtra(EncryptActivity.EXTRA_SIGNATURE_KEY_ID, mSecretKeyId); - intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, new long[]{mSignatureKeyId}); - startActivity(intent); - } - private void askForOutputFilename() { // Message is received after passphrase is cached Handler returnHandler = new Handler() { @@ -620,8 +672,8 @@ public class DecryptActivity extends DrawerActivity { } else { data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); - String message = mMessage.getText().toString(); - data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, message.getBytes()); +// String message = mMessage.getText().toString(); +// data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, message.getBytes()); } data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyId); @@ -647,20 +699,20 @@ public class DecryptActivity extends DrawerActivity { AppMsg.makeText(DecryptActivity.this, R.string.decryption_successful, AppMsg.STYLE_INFO).show(); - if (mReturnResult) { - Intent intent = new Intent(); - intent.putExtras(returnData); - setResult(RESULT_OK, intent); - finish(); - return; - } +// if (mReturnResult) { +// Intent intent = new Intent(); +// intent.putExtras(returnData); +// setResult(RESULT_OK, intent); +// finish(); +// return; +// } switch (mDecryptTarget) { case Id.target.message: String decryptedMessage = returnData .getString(KeychainIntentService.RESULT_DECRYPTED_STRING); - mMessage.setText(decryptedMessage); - mMessage.setHorizontallyScrolling(false); +// mMessage.setText(decryptedMessage); +// mMessage.setHorizontallyScrolling(false); break; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java new file mode 100644 index 000000000..0c8fd8c83 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; + +import org.sufficientlysecure.keychain.R; + +public class DecryptFileFragment extends Fragment { + + private EditText mMessage; + + /** + * Creates new instance of this fragment + */ + public static DecryptFileFragment newInstance() { + DecryptFileFragment frag = new DecryptFileFragment(); + + Bundle args = new Bundle(); + frag.setArguments(args); + + return frag; + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.decrypt_file_fragment, container, false); + + mMessage = (EditText) view.findViewById(R.id.message); + + return view; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java new file mode 100644 index 000000000..3fa7e89ba --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.EditText; + +import com.beardedhen.androidbootstrap.BootstrapButton; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; +import org.sufficientlysecure.keychain.util.Log; + +public class DecryptMessageFragment extends Fragment { + + private EditText mMessage; + + /** + * Creates new instance of this fragment + */ + public static DecryptMessageFragment newInstance() { + DecryptMessageFragment frag = new DecryptMessageFragment(); + + Bundle args = new Bundle(); + frag.setArguments(args); + + return frag; + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.decrypt_message_fragment, container, false); + + mMessage = (EditText) view.findViewById(R.id.message); + + return view; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + Log.d(Constants.TAG, "tag: " + getTag()); + } + + public String getText() { + return mMessage.getText().toString(); + } + + public void setText(String message) { + mMessage.setText(message); + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PageTabStripAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PageTabStripAdapter.java new file mode 100644 index 000000000..402699623 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PageTabStripAdapter.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.ui.adapter; + +import android.content.Context; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.app.FragmentTransaction; +import android.support.v4.view.ViewPager; +import android.support.v7.app.ActionBar; +import android.support.v7.app.ActionBarActivity; + +import java.util.ArrayList; + +public class PageTabStripAdapter extends FragmentPagerAdapter { + private final Context mContext; + private final ArrayList mTabs = new ArrayList(); + + static final class TabInfo { + private final Class clss; + private final Bundle args; + private final String title; + + TabInfo(Class clss, Bundle args, String title) { + this.clss = clss; + this.args = args; + this.title = title; + } + } + + public PageTabStripAdapter(ActionBarActivity activity) { + super(activity.getSupportFragmentManager()); + mContext = activity; + } + + public void addTab(Class clss, Bundle args, String title) { + TabInfo info = new TabInfo(clss, args, title); + mTabs.add(info); + notifyDataSetChanged(); + } + + @Override + public int getCount() { + return mTabs.size(); + } + + @Override + public Fragment getItem(int position) { + TabInfo info = mTabs.get(position); + return Fragment.instantiate(mContext, info.clss.getName(), info.args); + } + + @Override + public CharSequence getPageTitle(int position) { + return mTabs.get(position).title; + } +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java index f435d46ef..6dbea61dc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java @@ -36,12 +36,12 @@ public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar. private final ArrayList mTabs = new ArrayList(); static final class TabInfo { - private final Class mClss; - private final Bundle mArgs; + private final Class clss; + private final Bundle args; - TabInfo(Class mClss, Bundle mArgs) { - this.mClss = mClss; - this.mArgs = mArgs; + TabInfo(Class clss, Bundle args) { + this.clss = clss; + this.args = args; } } @@ -71,7 +71,7 @@ public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar. @Override public Fragment getItem(int position) { TabInfo info = mTabs.get(position); - return Fragment.instantiate(mContext, info.mClss.getName(), info.mArgs); + return Fragment.instantiate(mContext, info.clss.getName(), info.args); } public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { -- cgit v1.2.3 From 2947ab7e483e90d054f88ed267ea1160fd5b2f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 30 Mar 2014 18:37:32 +0200 Subject: More experimental work on decrypt fragments --- .../keychain/pgp/PgpDecryptVerify.java | 11 +- .../keychain/pgp/PgpDecryptVerifyResult.java | 38 +- .../sufficientlysecure/keychain/pgp/PgpHelper.java | 3 +- .../keychain/remote/OpenPgpService.java | 4 +- .../keychain/service/KeychainIntentService.java | 27 +- .../keychain/ui/DecryptActivity.java | 566 +++++++++------------ .../keychain/ui/DecryptFileFragment.java | 100 +++- .../keychain/ui/DecryptMessageFragment.java | 193 ++++++- .../keychain/ui/DecryptSignatureResultDisplay.java | 27 + .../ui/dialog/PassphraseDialogFragment.java | 29 +- 10 files changed, 623 insertions(+), 375 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptSignatureResultDisplay.java (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 571729bc5..d06898c89 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -75,7 +75,7 @@ public class PgpDecryptVerify { // optional private ProgressDialogUpdater mProgressDialogUpdater = null; private boolean mAssumeSymmetric = false; - private String mPassphrase = ""; + private String mPassphrase = null; private long mEnforcedKeyId = 0; public Builder(Context context, InputData data, OutputStream outStream) { @@ -253,8 +253,6 @@ public class PgpDecryptVerify { encryptedData = pbe; currentProgress += 5; } else { - updateProgress(R.string.progress_finding_key, currentProgress, 100); - PGPPublicKeyEncryptedData pbe = null; PGPSecretKey secretKey = null; Iterator it = enc.getEncryptedDataObjects(); @@ -262,6 +260,8 @@ public class PgpDecryptVerify { while (it.hasNext()) { Object obj = it.next(); if (obj instanceof PGPPublicKeyEncryptedData) { + updateProgress(R.string.progress_finding_key, currentProgress, 100); + PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; secretKey = ProviderHelper.getPGPSecretKeyByKeyId(mContext, encData.getKeyID()); if (secretKey != null) { @@ -294,14 +294,15 @@ public class PgpDecryptVerify { // if passphrase was not cached, return here // indicating that a passphrase is missing! if (mPassphrase == null) { - returnData.setKeyPassphraseNeeded(true); + returnData.setKeyIdPassphraseNeeded(encData.getKeyID()); + returnData.setStatus(PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED); return returnData; } } break; } - + } else if (obj instanceof PGPPBEEncryptedData) { } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java index d4a4f6075..ad240e834 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java @@ -19,27 +19,33 @@ package org.sufficientlysecure.keychain.pgp; import android.os.Parcel; import android.os.Parcelable; + import org.openintents.openpgp.OpenPgpSignatureResult; public class PgpDecryptVerifyResult implements Parcelable { - boolean mSymmetricPassphraseNeeded; - boolean mKeyPassphraseNeeded; + public static final int SUCCESS = 1; + public static final int KEY_PASSHRASE_NEEDED = 2; + public static final int SYMMETRIC_PASSHRASE_NEEDED = 3; + + int mStatus; + long mKeyIdPassphraseNeeded; + OpenPgpSignatureResult mSignatureResult; - public boolean isSymmetricPassphraseNeeded() { - return mSymmetricPassphraseNeeded; + public int getStatus() { + return mStatus; } - public void setSymmetricPassphraseNeeded(boolean symmetricPassphraseNeeded) { - this.mSymmetricPassphraseNeeded = symmetricPassphraseNeeded; + public void setStatus(int mStatus) { + this.mStatus = mStatus; } - public boolean isKeyPassphraseNeeded() { - return mKeyPassphraseNeeded; + public long getKeyIdPassphraseNeeded() { + return mKeyIdPassphraseNeeded; } - public void setKeyPassphraseNeeded(boolean keyPassphraseNeeded) { - this.mKeyPassphraseNeeded = keyPassphraseNeeded; + public void setKeyIdPassphraseNeeded(long mKeyIdPassphraseNeeded) { + this.mKeyIdPassphraseNeeded = mKeyIdPassphraseNeeded; } public OpenPgpSignatureResult getSignatureResult() { @@ -55,8 +61,8 @@ public class PgpDecryptVerifyResult implements Parcelable { } public PgpDecryptVerifyResult(PgpDecryptVerifyResult b) { - this.mSymmetricPassphraseNeeded = b.mSymmetricPassphraseNeeded; - this.mKeyPassphraseNeeded = b.mKeyPassphraseNeeded; + this.mStatus = b.mStatus; + this.mKeyIdPassphraseNeeded = b.mKeyIdPassphraseNeeded; this.mSignatureResult = b.mSignatureResult; } @@ -66,16 +72,16 @@ public class PgpDecryptVerifyResult implements Parcelable { } public void writeToParcel(Parcel dest, int flags) { - dest.writeByte((byte) (mSymmetricPassphraseNeeded ? 1 : 0)); - dest.writeByte((byte) (mKeyPassphraseNeeded ? 1 : 0)); + dest.writeInt(mStatus); + dest.writeLong(mKeyIdPassphraseNeeded); dest.writeParcelable(mSignatureResult, 0); } public static final Creator CREATOR = new Creator() { public PgpDecryptVerifyResult createFromParcel(final Parcel source) { PgpDecryptVerifyResult vr = new PgpDecryptVerifyResult(); - vr.mSymmetricPassphraseNeeded = source.readByte() == 1; - vr.mKeyPassphraseNeeded = source.readByte() == 1; + vr.mStatus = source.readInt(); + vr.mKeyIdPassphraseNeeded = source.readLong(); vr.mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader()); return vr; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java index 2680d77af..cc40afbac 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java @@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.pgp; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; + import org.spongycastle.openpgp.*; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; @@ -43,7 +44,7 @@ public class PgpHelper { public static final Pattern PGP_MESSAGE = Pattern.compile( ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL); - public static final Pattern PGP_SIGNED_MESSAGE = Pattern + public static final Pattern PGP_CLEARTEXT_SIGNATURE = Pattern .compile( ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", Pattern.DOTALL); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index f85e342d8..1d3bb88df 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -298,11 +298,11 @@ public class OpenPgpService extends RemoteService { // TODO: currently does not support binary signed-only content PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute(); - if (decryptVerifyResult.isKeyPassphraseNeeded()) { + if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { // get PendingIntent for passphrase input, add it to given params and return to client Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId()); return passphraseBundle; - } else if (decryptVerifyResult.isSymmetricPassphraseNeeded()) { + } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { throw new PgpGeneralException("Decryption of symmetric content not supported by API!"); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 846eb8cf9..2cc3798e0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -100,9 +100,9 @@ public class KeychainIntentService extends IntentService public static final String ENCRYPT_PROVIDER_URI = "provider_uri"; // decrypt/verify - public static final String DECRYPT_RETURN_BYTES = "return_binary"; public static final String DECRYPT_CIPHERTEXT_BYTES = "ciphertext_bytes"; public static final String DECRYPT_ASSUME_SYMMETRIC = "assume_symmetric"; + public static final String DECRYPT_PASSPHRASE = "passphrase"; // save keyring public static final String SAVE_KEYRING_PARCEL = "save_parcel"; @@ -155,7 +155,6 @@ public class KeychainIntentService extends IntentService public static final String RESULT_URI = "result_uri"; // decrypt/verify - public static final String RESULT_DECRYPTED_STRING = "decrypted_message"; public static final String RESULT_DECRYPTED_BYTES = "decrypted_data"; public static final String RESULT_DECRYPT_VERIFY_RESULT = "signature"; @@ -387,15 +386,14 @@ public class KeychainIntentService extends IntentService /* Input */ int target = data.getInt(TARGET); - long secretKeyId = data.getLong(ENCRYPT_SECRET_KEY_ID); byte[] bytes = data.getByteArray(DECRYPT_CIPHERTEXT_BYTES); - boolean returnBytes = data.getBoolean(DECRYPT_RETURN_BYTES); boolean assumeSymmetricEncryption = data.getBoolean(DECRYPT_ASSUME_SYMMETRIC); + String passphrase = data.getString(DECRYPT_PASSPHRASE); - InputStream inStream = null; - long inLength = -1; - InputData inputData = null; - OutputStream outStream = null; + InputStream inStream; + long inLength; + InputData inputData; + OutputStream outStream; String streamFilename = null; switch (target) { case TARGET_BYTES: /* decrypting bytes directly */ @@ -469,7 +467,7 @@ public class KeychainIntentService extends IntentService builder.progressDialogUpdater(this); builder.assumeSymmetric(assumeSymmetricEncryption) - .passphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); + .passphrase(passphrase); PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute(); @@ -481,15 +479,8 @@ public class KeychainIntentService extends IntentService switch (target) { case TARGET_BYTES: - if (returnBytes) { - byte output[] = ((ByteArrayOutputStream) outStream).toByteArray(); - resultData.putByteArray(RESULT_DECRYPTED_BYTES, output); - } else { - String output = new String( - ((ByteArrayOutputStream) outStream).toByteArray()); - resultData.putString(RESULT_DECRYPTED_STRING, output); - } - + byte output[] = ((ByteArrayOutputStream) outStream).toByteArray(); + resultData.putByteArray(RESULT_DECRYPTED_BYTES, output); break; case TARGET_URI: // nothing, file was written, just send okay and verification bundle diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 24a8854af..21e51dcd9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -17,8 +17,6 @@ package org.sufficientlysecure.keychain.ui; -import android.annotation.SuppressLint; -import android.app.ProgressDialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -30,7 +28,6 @@ import android.support.v4.view.PagerTabStrip; import android.support.v4.view.ViewPager; import android.view.View; import android.view.View.OnClickListener; -import android.view.animation.AnimationUtils; import android.widget.*; import com.beardedhen.androidbootstrap.BootstrapButton; @@ -41,21 +38,16 @@ import org.spongycastle.openpgp.PGPPublicKeyRing; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.exception.NoAsymmetricEncryptionException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.KeychainIntentService; -import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.ui.adapter.PageTabStripAdapter; -import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; @@ -64,7 +56,8 @@ import java.io.*; import java.util.regex.Matcher; //@SuppressLint("NewApi") -public class DecryptActivity extends DrawerActivity { +public class DecryptActivity extends DrawerActivity implements DecryptSignatureResultDisplay { + /* Intents */ // without permission @@ -122,43 +115,13 @@ public class DecryptActivity extends DrawerActivity { ViewPager mViewPager; PagerTabStrip mPagerTabStrip; PageTabStripAdapter mTabsAdapter; - DecryptMessageFragment mMessageFragment; - DecryptFileFragment mFileFragment; - private void initView() { -// mSource = (ViewFlipper) findViewById(R.id.source); -// mSourceLabel = (TextView) findViewById(R.id.sourceLabel); -// mSourcePrevious = (ImageView) findViewById(R.id.sourcePrevious); -// mSourceNext = (ImageView) findViewById(R.id.sourceNext); -// -// mSourcePrevious.setClickable(true); -// mSourcePrevious.setOnClickListener(new OnClickListener() { -// public void onClick(View v) { -// mSource.setInAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, -// R.anim.push_right_in)); -// mSource.setOutAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, -// R.anim.push_right_out)); -// mSource.showPrevious(); -// updateSource(); -// } -// }); -// -// mSourceNext.setClickable(true); -// OnClickListener nextSourceClickListener = new OnClickListener() { -// public void onClick(View v) { -// mSource.setInAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, -// R.anim.push_left_in)); -// mSource.setOutAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, -// R.anim.push_left_out)); -// mSource.showNext(); -// updateSource(); -// } -// }; -// mSourceNext.setOnClickListener(nextSourceClickListener); -// -// mSourceLabel.setClickable(true); -// mSourceLabel.setOnClickListener(nextSourceClickListener); + private static final int PAGER_TAB_MESSAGE = 0; + private static final int PAGER_TAB_FILE = 1; + + + private void initView() { mSignatureLayout = (RelativeLayout) findViewById(R.id.signature); mSignatureStatusImage = (ImageView) findViewById(R.id.ic_signature_status); mUserId = (TextView) findViewById(R.id.mainUserId); @@ -171,24 +134,24 @@ public class DecryptActivity extends DrawerActivity { // int height = tmp.getMeasuredHeight(); // mMessage.setMinimumHeight(height); - mFilename = (EditText) findViewById(R.id.filename); - mBrowse = (BootstrapButton) findViewById(R.id.btn_browse); - mBrowse.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - FileHelper.openFile(DecryptActivity.this, mFilename.getText().toString(), "*/*", - RESULT_CODE_FILE); - } - }); - - mLookupKey = (BootstrapButton) findViewById(R.id.lookup_key); - mLookupKey.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - lookupUnknownKey(mSignatureKeyId); - } - }); - - mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterDecryption); +// mFilename = (EditText) findViewById(R.id.filename); +// mBrowse = (BootstrapButton) findViewById(R.id.btn_browse); +// mBrowse.setOnClickListener(new View.OnClickListener() { +// public void onClick(View v) { +// FileHelper.openFile(DecryptActivity.this, mFilename.getText().toString(), "*/*", +// RESULT_CODE_FILE); +// } +// }); +// +// mLookupKey = (BootstrapButton) findViewById(R.id.lookup_key); +// mLookupKey.setOnClickListener(new OnClickListener() { +// @Override +// public void onClick(View v) { +// lookupUnknownKey(mSignatureKeyId); +// } +// }); +// +// mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterDecryption); // default: message source // mSource.setInAnimation(null); @@ -197,23 +160,19 @@ public class DecryptActivity extends DrawerActivity { // mSource.showNext(); // } - mDecryptButton = (BootstrapButton) findViewById(R.id.action_decrypt); - mDecryptButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - decryptClicked(); - } - }); +// mDecryptButton = (BootstrapButton) findViewById(R.id.action_decrypt); +// mDecryptButton.setOnClickListener(new OnClickListener() { +// @Override +// public void onClick(View v) { +// decryptClicked(); +// } +// }); + + // Pager mViewPager = (ViewPager) findViewById(R.id.decrypt_pager); mPagerTabStrip = (PagerTabStrip) findViewById(R.id.decrypt_pager_tab_strip); - initPager(); - } - private static final int PAGER_TAB_MESSAGE = 0; - private static final int PAGER_TAB_FILE = 1; - - private void initPager() { mTabsAdapter = new PageTabStripAdapter(this); mViewPager.setAdapter(mTabsAdapter); @@ -222,20 +181,9 @@ public class DecryptActivity extends DrawerActivity { Bundle fileBundle = new Bundle(); mTabsAdapter.addTab(DecryptFileFragment.class, fileBundle, getString(R.string.label_file)); - -// mPagerTabStrip. - getSupportFragmentManager().executePendingTransactions(); -// for (Fragment f : getSupportFragmentManager().getFragments()) { -// Log.d(Constants.TAG, "f: "+f.getTag()); -// } - - DecryptMessageFragment messageFragment = (DecryptMessageFragment) getFragmentByPosition(PAGER_TAB_MESSAGE); -// mFileFragment = (DecryptFileFragment) getFragmentByPosition(PAGER_TAB_FILE); - -// Log.d(Constants.TAG, fr.getTag()); -// } + /** * find fragment * @@ -265,26 +213,6 @@ public class DecryptActivity extends DrawerActivity { // Handle intent actions handleActions(getIntent()); -// if (mSource.getCurrentView().getId() == R.id.sourceMessage -// && mMessage.getText().length() == 0) { -// -// CharSequence clipboardText = ClipboardReflection.getClipboardText(this); -// -// String data = ""; -// if (clipboardText != null) { -// Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText); -// if (!matcher.matches()) { -// matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(clipboardText); -// } -// if (matcher.matches()) { -// data = matcher.group(1); -// mMessage.setText(data); -// AppMsg.makeText(this, R.string.using_clipboard_content, AppMsg.STYLE_INFO) -// .show(); -// } -// } -// } - mSignatureLayout.setVisibility(View.GONE); mSignatureLayout.setOnClickListener(new OnClickListener() { public void onClick(View v) { @@ -301,27 +229,6 @@ public class DecryptActivity extends DrawerActivity { } } }); - -// if (mReturnResult) { -// mSourcePrevious.setClickable(false); -// mSourcePrevious.setEnabled(false); -// mSourcePrevious.setVisibility(View.INVISIBLE); -// -// mSourceNext.setClickable(false); -// mSourceNext.setEnabled(false); -// mSourceNext.setVisibility(View.INVISIBLE); -// -// mSourceLabel.setClickable(false); -// mSourceLabel.setEnabled(false); -// } -// -// updateSource(); - -// if (mDecryptImmediately -// || (mSource.getCurrentView().getId() == R.id.sourceMessage && (mMessage.getText() -// .length() > 0 || mContentUri != null))) { -// decryptClicked(); -// } } @@ -381,20 +288,20 @@ public class DecryptActivity extends DrawerActivity { // replace non breakable spaces textData = textData.replaceAll("\\xa0", " "); - mViewPager.setCurrentItem(PAGER_TAB_MESSAGE, false); - mMessageFragment.setText(textData); +// mViewPager.setCurrentItem(PAGER_TAB_MESSAGE, false); +// mMessageFragment.setText(textData); // mMessage.setText(textData); } else { - matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(textData); + matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(textData); if (matcher.matches()) { - Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched"); + Log.d(Constants.TAG, "PGP_CLEARTEXT_SIGNATURE matched"); textData = matcher.group(1); // replace non breakable spaces textData = textData.replaceAll("\\xa0", " "); // mMessage.setText(textData); - mViewPager.setCurrentItem(PAGER_TAB_MESSAGE, false); - mMessageFragment = (DecryptMessageFragment) getFragmentByPosition(mViewPager.getCurrentItem()); - mMessageFragment.setText(textData); +// mViewPager.setCurrentItem(PAGER_TAB_MESSAGE, false); +// mMessageFragment = (DecryptMessageFragment) getFragmentByPosition(mViewPager.getCurrentItem()); +// mMessageFragment.setText(textData); } else { Log.d(Constants.TAG, "Nothing matched!"); } @@ -426,34 +333,14 @@ public class DecryptActivity extends DrawerActivity { } } - private void guessOutputFilename() { - mInputFilename = mFilename.getText().toString(); - File file = new File(mInputFilename); - String filename = file.getName(); - if (filename.endsWith(".asc") || filename.endsWith(".gpg") || filename.endsWith(".pgp")) { - filename = filename.substring(0, filename.length() - 4); - } - mOutputFilename = Constants.Path.APP_DIR + "/" + filename; - } - -// private void updateSource() { -// switch (mSource.getCurrentView().getId()) { -// case R.id.sourceFile: { -// mSourceLabel.setText(R.string.label_file); -// mDecryptButton.setText(getString(R.string.btn_decrypt)); -// break; -// } -// -// case R.id.sourceMessage: { -// mSourceLabel.setText(R.string.label_message); -// mDecryptButton.setText(getString(R.string.btn_decrypt)); -// break; -// } -// -// default: { -// break; -// } +// private void guessOutputFilename() { +// mInputFilename = mFilename.getText().toString(); +// File file = new File(mInputFilename); +// String filename = file.getName(); +// if (filename.endsWith(".asc") || filename.endsWith(".gpg") || filename.endsWith(".pgp")) { +// filename = filename.substring(0, filename.length() - 4); // } +// mOutputFilename = Constants.Path.APP_DIR + "/" + filename; // } private void decryptClicked() { @@ -492,7 +379,7 @@ public class DecryptActivity extends DrawerActivity { if (mDecryptTarget == Id.target.message) { // String messageData = mMessage.getText().toString(); -// Matcher matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(messageData); +// Matcher matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(messageData); // if (matcher.matches()) { // mSignedOnly = true; // decryptStart(); @@ -512,7 +399,7 @@ public class DecryptActivity extends DrawerActivity { if (mDecryptTarget == Id.target.file) { askForOutputFilename(); } else { // mDecryptTarget == Id.target.message - decryptStart(); +// decryptStart(); } } } @@ -531,7 +418,7 @@ public class DecryptActivity extends DrawerActivity { if (mDecryptTarget == Id.target.file) { askForOutputFilename(); } else { - decryptStart(); +// decryptStart(); } } } @@ -623,7 +510,7 @@ public class DecryptActivity extends DrawerActivity { if (message.what == FileDialogFragment.MESSAGE_OKAY) { Bundle data = message.getData(); mOutputFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); - decryptStart(); +// decryptStart(); } } }; @@ -645,156 +532,156 @@ public class DecryptActivity extends DrawerActivity { startActivityForResult(intent, RESULT_CODE_LOOKUP_KEY); } - private void decryptStart() { - Log.d(Constants.TAG, "decryptStart"); - - // Send all information needed to service to decrypt in other thread - Intent intent = new Intent(this, KeychainIntentService.class); - - // fill values for this action - Bundle data = new Bundle(); - - intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY); - - // choose action based on input: decrypt stream, file or bytes - if (mContentUri != null) { - data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_STREAM); - - data.putParcelable(KeychainIntentService.ENCRYPT_PROVIDER_URI, mContentUri); - } else if (mDecryptTarget == Id.target.file) { - data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI); - - Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" - + mOutputFilename); - - data.putString(KeychainIntentService.ENCRYPT_INPUT_FILE, mInputFilename); - data.putString(KeychainIntentService.ENCRYPT_OUTPUT_FILE, mOutputFilename); - } else { - data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); - -// String message = mMessage.getText().toString(); -// data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, message.getBytes()); - } - - data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyId); - - data.putBoolean(KeychainIntentService.DECRYPT_RETURN_BYTES, mReturnBinary); - data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, mAssumeSymmetricEncryption); - - intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - - // Message is received after encrypting is done in KeychainIntentService - KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, - getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) { - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { - // get returned data bundle - Bundle returnData = message.getData(); - - mSignatureKeyId = 0; - mSignatureLayout.setVisibility(View.GONE); - - AppMsg.makeText(DecryptActivity.this, R.string.decryption_successful, - AppMsg.STYLE_INFO).show(); -// if (mReturnResult) { -// Intent intent = new Intent(); -// intent.putExtras(returnData); -// setResult(RESULT_OK, intent); -// finish(); -// return; +// private void decryptStart() { +// Log.d(Constants.TAG, "decryptStart"); +// +// // Send all information needed to service to decrypt in other thread +// Intent intent = new Intent(this, KeychainIntentService.class); +// +// // fill values for this action +// Bundle data = new Bundle(); +// +// intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY); +// +// // choose action based on input: decrypt stream, file or bytes +// if (mContentUri != null) { +// data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_STREAM); +// +// data.putParcelable(KeychainIntentService.ENCRYPT_PROVIDER_URI, mContentUri); +// } else if (mDecryptTarget == Id.target.file) { +// data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI); +// +// Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" +// + mOutputFilename); +// +// data.putString(KeychainIntentService.ENCRYPT_INPUT_FILE, mInputFilename); +// data.putString(KeychainIntentService.ENCRYPT_OUTPUT_FILE, mOutputFilename); +// } else { +// data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); +// +//// String message = mMessage.getText().toString(); +//// data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, message.getBytes()); +// } +// +// data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyId); +// +// data.putBoolean(KeychainIntentService.DECRYPT_RETURN_BYTES, mReturnBinary); +// data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, mAssumeSymmetricEncryption); +// +// intent.putExtra(KeychainIntentService.EXTRA_DATA, data); +// +// // Message is received after encrypting is done in KeychainIntentService +// KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, +// getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) { +// public void handleMessage(Message message) { +// // handle messages by standard KeychainIntentServiceHandler first +// super.handleMessage(message); +// +// if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { +// // get returned data bundle +// Bundle returnData = message.getData(); +// +// mSignatureKeyId = 0; +// mSignatureLayout.setVisibility(View.GONE); +// +// AppMsg.makeText(DecryptActivity.this, R.string.decryption_successful, +// AppMsg.STYLE_INFO).show(); +//// if (mReturnResult) { +//// Intent intent = new Intent(); +//// intent.putExtras(returnData); +//// setResult(RESULT_OK, intent); +//// finish(); +//// return; +//// } +// +// switch (mDecryptTarget) { +// case Id.target.message: +// String decryptedMessage = returnData +// .getString(KeychainIntentService.RESULT_DECRYPTED_STRING); +//// mMessage.setText(decryptedMessage); +//// mMessage.setHorizontallyScrolling(false); +// +// break; +// +// case Id.target.file: +// if (mDeleteAfter.isChecked()) { +// // Create and show dialog to delete original file +// DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment +// .newInstance(mInputFilename); +// deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); +// } +// break; +// +// default: +// // shouldn't happen +// break; +// // } - - switch (mDecryptTarget) { - case Id.target.message: - String decryptedMessage = returnData - .getString(KeychainIntentService.RESULT_DECRYPTED_STRING); -// mMessage.setText(decryptedMessage); -// mMessage.setHorizontallyScrolling(false); - - break; - - case Id.target.file: - if (mDeleteAfter.isChecked()) { - // Create and show dialog to delete original file - DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment - .newInstance(mInputFilename); - deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); - } - break; - - default: - // shouldn't happen - break; - - } - - PgpDecryptVerifyResult decryptVerifyResult = - returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT); - - OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); - - if (signatureResult != null) { - - String userId = signatureResult.getUserId(); - mSignatureKeyId = signatureResult.getKeyId(); - mUserIdRest.setText("id: " - + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId)); - if (userId == null) { - userId = getResources().getString(R.string.user_id_no_name); - } - String chunks[] = userId.split(" <", 2); - userId = chunks[0]; - if (chunks.length > 1) { - mUserIdRest.setText("<" + chunks[1]); - } - mUserId.setText(userId); - - switch (signatureResult.getStatus()) { - case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { - mSignatureStatusImage.setImageResource(R.drawable.overlay_ok); - mLookupKey.setVisibility(View.GONE); - break; - } - - // TODO! -// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { +// +// PgpDecryptVerifyResult decryptVerifyResult = +// returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT); +// +// OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); +// +// if (signatureResult != null) { +// +// String userId = signatureResult.getUserId(); +// mSignatureKeyId = signatureResult.getKeyId(); +// mUserIdRest.setText("id: " +// + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId)); +// if (userId == null) { +// userId = getResources().getString(R.string.user_id_no_name); +// } +// String chunks[] = userId.split(" <", 2); +// userId = chunks[0]; +// if (chunks.length > 1) { +// mUserIdRest.setText("<" + chunks[1]); +// } +// mUserId.setText(userId); +// +// switch (signatureResult.getStatus()) { +// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { +// mSignatureStatusImage.setImageResource(R.drawable.overlay_ok); +// mLookupKey.setVisibility(View.GONE); // break; // } - - case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: { - mSignatureStatusImage.setImageResource(R.drawable.overlay_error); - mLookupKey.setVisibility(View.VISIBLE); - AppMsg.makeText(DecryptActivity.this, - R.string.unknown_signature, - AppMsg.STYLE_ALERT).show(); - break; - } - - default: { - mSignatureStatusImage.setImageResource(R.drawable.overlay_error); - mLookupKey.setVisibility(View.GONE); - break; - } - } - mSignatureLayout.setVisibility(View.VISIBLE); - } - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - - // show progress dialog - saveHandler.showProgressDialog(this); - - // start service with intent - startService(intent); - } +// +// // TODO! +//// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { +//// break; +//// } +// +// case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: { +// mSignatureStatusImage.setImageResource(R.drawable.overlay_error); +// mLookupKey.setVisibility(View.VISIBLE); +// AppMsg.makeText(DecryptActivity.this, +// R.string.unknown_signature, +// AppMsg.STYLE_ALERT).show(); +// break; +// } +// +// default: { +// mSignatureStatusImage.setImageResource(R.drawable.overlay_error); +// mLookupKey.setVisibility(View.GONE); +// break; +// } +// } +// mSignatureLayout.setVisibility(View.VISIBLE); +// } +// } +// } +// }; +// +// // Create a new Messenger for the communication back +// Messenger messenger = new Messenger(saveHandler); +// intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); +// +// // show progress dialog +// saveHandler.showProgressDialog(this); +// +// // start service with intent +// startService(intent); +// } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { @@ -819,7 +706,7 @@ public class DecryptActivity extends DrawerActivity { Log.d(Constants.TAG, "Returning from Lookup Key..."); if (resultCode == RESULT_OK) { // decrypt again - decryptStart(); +// decryptStart(); } return; } @@ -832,4 +719,55 @@ public class DecryptActivity extends DrawerActivity { } } + @Override + public void onSignatureResult(OpenPgpSignatureResult signatureResult) { + + mSignatureKeyId = 0; + mSignatureLayout.setVisibility(View.GONE); + if (signatureResult != null) { + + String userId = signatureResult.getUserId(); + mSignatureKeyId = signatureResult.getKeyId(); + mUserIdRest.setText("id: " + + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId)); + if (userId == null) { + userId = getResources().getString(R.string.user_id_no_name); + } + String chunks[] = userId.split(" <", 2); + userId = chunks[0]; + if (chunks.length > 1) { + mUserIdRest.setText("<" + chunks[1]); + } + mUserId.setText(userId); + + switch (signatureResult.getStatus()) { + case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { + mSignatureStatusImage.setImageResource(R.drawable.overlay_ok); + mLookupKey.setVisibility(View.GONE); + break; + } + + // TODO! +// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { +// break; +// } + + case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: { + mSignatureStatusImage.setImageResource(R.drawable.overlay_error); + mLookupKey.setVisibility(View.VISIBLE); + AppMsg.makeText(DecryptActivity.this, + R.string.unknown_signature, + AppMsg.STYLE_ALERT).show(); + break; + } + + default: { + mSignatureStatusImage.setImageResource(R.drawable.overlay_error); + mLookupKey.setVisibility(View.GONE); + break; + } + } + mSignatureLayout.setVisibility(View.VISIBLE); + } + } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index 0c8fd8c83..3d40eaf09 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -18,17 +18,39 @@ package org.sufficientlysecure.keychain.ui; import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.CheckBox; import android.widget.EditText; +import com.beardedhen.androidbootstrap.BootstrapButton; +import com.devspark.appmsg.AppMsg; + +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.FileHelper; +import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; + +import java.io.File; public class DecryptFileFragment extends Fragment { - private EditText mMessage; + private EditText mFilename; + private CheckBox mDeleteAfter; + private BootstrapButton mBrowse; + private BootstrapButton mDecryptButton; + + + private String mInputFilename = null; + private String mOutputFilename = null; + + private static final int RESULT_CODE_FILE = 0x00007003; + /** * Creates new instance of this fragment @@ -49,14 +71,88 @@ public class DecryptFileFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.decrypt_file_fragment, container, false); - mMessage = (EditText) view.findViewById(R.id.message); + mFilename = (EditText) findViewById(R.id.filename); + mBrowse = (BootstrapButton) findViewById(R.id.btn_browse); + mBrowse.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + FileHelper.openFile(DecryptActivity.this, mFilename.getText().toString(), "*/*", + RESULT_CODE_FILE); + } + }); + mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterDecryption); + mDecryptButton = (BootstrapButton) view.findViewById(R.id.action_decrypt); + mDecryptButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + decryptAction(); + } + }); return view; } + private void guessOutputFilename() { + mInputFilename = mFilename.getText().toString(); + File file = new File(mInputFilename); + String filename = file.getName(); + if (filename.endsWith(".asc") || filename.endsWith(".gpg") || filename.endsWith(".pgp")) { + filename = filename.substring(0, filename.length() - 4); + } + mOutputFilename = Constants.Path.APP_DIR + "/" + filename; + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } + private void decryptAction() { + String currentFilename = mFilename.getText().toString(); + if (mInputFilename == null || !mInputFilename.equals(currentFilename)) { + guessOutputFilename(); + } + + if (mInputFilename.equals("")) { + AppMsg.makeText(getActivity(), R.string.no_file_selected, AppMsg.STYLE_ALERT).show(); + return; + } + + if (mInputFilename.startsWith("file")) { + File file = new File(mInputFilename); + if (!file.exists() || !file.isFile()) { + AppMsg.makeText( + getActivity(), + getString(R.string.error_message, + getString(R.string.error_file_not_found)), AppMsg.STYLE_ALERT) + .show(); + return; + } + } + + askForOutputFilename(); + } + + private void askForOutputFilename() { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == FileDialogFragment.MESSAGE_OKAY) { + Bundle data = message.getData(); + mOutputFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); +// decryptStart(); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + mFileDialog = FileDialogFragment.newInstance(messenger, + getString(R.string.title_decrypt_to_file), + getString(R.string.specify_file_to_decrypt_to), mOutputFilename, null); + + mFileDialog.show(getSupportFragmentManager(), "fileDialog"); + } + } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java index 3fa7e89ba..c6724f6d1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java @@ -17,7 +17,13 @@ package org.sufficientlysecure.keychain.ui; +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Intent; import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; @@ -26,27 +32,30 @@ import android.view.ViewGroup; import android.widget.EditText; import com.beardedhen.androidbootstrap.BootstrapButton; +import com.devspark.appmsg.AppMsg; +import org.openintents.openpgp.OpenPgpSignatureResult; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; +import org.sufficientlysecure.keychain.pgp.PgpHelper; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; +import java.util.regex.Matcher; + public class DecryptMessageFragment extends Fragment { + DecryptSignatureResultDisplay mSignatureResultDisplay; private EditText mMessage; + private BootstrapButton mDecryptButton; + private BootstrapButton mDecryptFromCLipboardButton; - /** - * Creates new instance of this fragment - */ - public static DecryptMessageFragment newInstance() { - DecryptMessageFragment frag = new DecryptMessageFragment(); - - Bundle args = new Bundle(); - frag.setArguments(args); - - return frag; - } + public static final String EXTRA_CIPHERTEXT = "ciphertext"; /** * Inflate the layout for this fragment @@ -56,23 +65,175 @@ public class DecryptMessageFragment extends Fragment { View view = inflater.inflate(R.layout.decrypt_message_fragment, container, false); mMessage = (EditText) view.findViewById(R.id.message); + mDecryptButton = (BootstrapButton) view.findViewById(R.id.action_decrypt); + mDecryptFromCLipboardButton = (BootstrapButton) view.findViewById(R.id.action_decrypt_from_clipboard); + + String ciphertext = getArguments().getString(EXTRA_CIPHERTEXT); + if (ciphertext != null) { + mMessage.setText(ciphertext); + } + + mDecryptButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + decryptAction(); + } + }); + + mDecryptFromCLipboardButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + decryptFromClipboard(); + } + }); return view; } + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + mSignatureResultDisplay = (DecryptSignatureResultDisplay) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + " must implement DecryptSignatureResultDisplay"); + } + } + + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - Log.d(Constants.TAG, "tag: " + getTag()); + Log.d(Constants.TAG, "onActivityCreated tag: " + getTag()); + + } - public String getText() { - return mMessage.getText().toString(); + private void decryptFromClipboard() { + CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity()); + + if (clipboardText != null) { + Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText); + if (!matcher.matches()) { + matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(clipboardText); + } + if (matcher.matches()) { + String data = matcher.group(1); + mMessage.setText(data); + decryptStart(null); + } else { + AppMsg.makeText(getActivity(), R.string.error_invalid_data, AppMsg.STYLE_INFO) + .show(); + } + } else { + AppMsg.makeText(getActivity(), R.string.error_invalid_data, AppMsg.STYLE_INFO) + .show(); + } } - public void setText(String message) { - mMessage.setText(message); + private void decryptAction() { + decryptStart(null); } + private void decryptStart(String passphrase) { + Log.d(Constants.TAG, "decryptStart"); + + // Send all information needed to service to decrypt in other thread + Intent intent = new Intent(getActivity(), KeychainIntentService.class); + + // fill values for this action + Bundle data = new Bundle(); + + intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY); + + // data + data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); + String message = mMessage.getText().toString(); + data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, message.getBytes()); + data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, passphrase); + + // TODO + data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, false); + + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Message is received after encrypting is done in KeychainIntentService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(), + getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle returnData = message.getData(); + + + PgpDecryptVerifyResult decryptVerifyResult = + returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT); + + if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { + showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded()); + } else { + + AppMsg.makeText(getActivity(), R.string.decryption_successful, + AppMsg.STYLE_INFO).show(); + + byte[] decryptedMessage = returnData + .getByteArray(KeychainIntentService.RESULT_DECRYPTED_BYTES); + mMessage.setText(new String(decryptedMessage)); + mMessage.setHorizontallyScrolling(false); + + + OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); + + // display signature result in activity + mSignatureResultDisplay.onSignatureResult(signatureResult); + } + + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(getActivity()); + + // start service with intent + getActivity().startService(intent); + } + + private void showPassphraseDialog(long keyId) { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + String passphrase = + message.getData().getString(PassphraseDialogFragment.MESSAGE_DATA_PASSPHRASE); + decryptStart(passphrase); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + try { + PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(getActivity(), + messenger, keyId); + + passphraseDialog.show(getActivity().getSupportFragmentManager(), "passphraseDialog"); + } catch (PgpGeneralException e) { + Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); + // send message to handler to start encryption directly + returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); + } + } + + } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptSignatureResultDisplay.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptSignatureResultDisplay.java new file mode 100644 index 000000000..e167064ec --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptSignatureResultDisplay.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.ui; + +import org.openintents.openpgp.OpenPgpSignatureResult; + +public interface DecryptSignatureResultDisplay { + + public void onSignatureResult(OpenPgpSignatureResult result); + +} + diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java index 271219fa3..3c8b872b0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java @@ -59,6 +59,8 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor public static final int MESSAGE_OKAY = 1; public static final int MESSAGE_CANCEL = 2; + public static final String MESSAGE_DATA_PASSPHRASE = "passphrase"; + private Messenger mMessenger; private EditText mPassphraseEditText; private boolean mCanKB; @@ -209,7 +211,11 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor passphrase); } - sendMessageToHandler(MESSAGE_OKAY); + // also return passphrase back to activity + Bundle data = new Bundle(); + data.putString(MESSAGE_DATA_PASSPHRASE, passphrase); + + sendMessageToHandler(MESSAGE_OKAY, data); } }); @@ -278,4 +284,25 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor } } + /** + * Send message back to handler which is initialized in a activity + * + * @param what Message integer you want to send + */ + private void sendMessageToHandler(Integer what, Bundle data) { + Message msg = Message.obtain(); + msg.what = what; + if (data != null) { + msg.setData(data); + } + + try { + mMessenger.send(msg); + } catch (RemoteException e) { + Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); + } catch (NullPointerException e) { + Log.w(Constants.TAG, "Messenger is null!", e); + } + } + } -- cgit v1.2.3 From ccce28acdbba740389b56c2ff0fccdf1b9304604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 30 Mar 2014 19:35:35 +0200 Subject: compiles again --- .../org/sufficientlysecure/keychain/ui/DecryptActivity.java | 4 ++-- .../sufficientlysecure/keychain/ui/DecryptFileFragment.java | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 21e51dcd9..2ffed07ff 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -313,7 +313,7 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR if (path != null) { mInputFilename = path; mFilename.setText(mInputFilename); - guessOutputFilename(); +// guessOutputFilename(); // mSource.setInAnimation(null); // mSource.setOutAnimation(null); // while (mSource.getCurrentView().getId() != R.id.sourceFile) { @@ -356,7 +356,7 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR if (mDecryptTarget == Id.target.file) { String currentFilename = mFilename.getText().toString(); if (mInputFilename == null || !mInputFilename.equals(currentFilename)) { - guessOutputFilename(); +// guessOutputFilename(); } if (mInputFilename.equals("")) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index 3d40eaf09..6646be8ee 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -49,6 +49,8 @@ public class DecryptFileFragment extends Fragment { private String mInputFilename = null; private String mOutputFilename = null; + private FileDialogFragment mFileDialog; + private static final int RESULT_CODE_FILE = 0x00007003; @@ -71,15 +73,15 @@ public class DecryptFileFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.decrypt_file_fragment, container, false); - mFilename = (EditText) findViewById(R.id.filename); - mBrowse = (BootstrapButton) findViewById(R.id.btn_browse); + mFilename = (EditText) view.findViewById(R.id.filename); + mBrowse = (BootstrapButton) view.findViewById(R.id.btn_browse); mBrowse.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - FileHelper.openFile(DecryptActivity.this, mFilename.getText().toString(), "*/*", + FileHelper.openFile(getActivity(), mFilename.getText().toString(), "*/*", RESULT_CODE_FILE); } }); - mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterDecryption); + mDeleteAfter = (CheckBox) view.findViewById(R.id.deleteAfterDecryption); mDecryptButton = (BootstrapButton) view.findViewById(R.id.action_decrypt); mDecryptButton.setOnClickListener(new View.OnClickListener() { @Override @@ -152,7 +154,7 @@ public class DecryptFileFragment extends Fragment { getString(R.string.title_decrypt_to_file), getString(R.string.specify_file_to_decrypt_to), mOutputFilename, null); - mFileDialog.show(getSupportFragmentManager(), "fileDialog"); + mFileDialog.show(getActivity().getSupportFragmentManager(), "fileDialog"); } } -- cgit v1.2.3 From 55a2cbe9c311ec7ed12d07491e34a48c60bc0ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 30 Mar 2014 20:53:16 +0200 Subject: Decrypt mostly works again --- .../keychain/service/KeychainIntentService.java | 57 +-- .../keychain/ui/DecryptActivity.java | 555 ++------------------- .../keychain/ui/DecryptFileFragment.java | 180 ++++++- .../keychain/ui/DecryptMessageFragment.java | 16 +- .../keychain/ui/adapter/PageTabStripAdapter.java | 74 --- .../keychain/ui/adapter/PagerTabStripAdapter.java | 74 +++ 6 files changed, 315 insertions(+), 641 deletions(-) delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PageTabStripAdapter.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 2cc3798e0..7ac1747b7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -428,29 +428,30 @@ public class KeychainIntentService extends IntentService break; - case TARGET_STREAM: /* decrypting stream from content uri */ - Uri providerUri = (Uri) data.getParcelable(ENCRYPT_PROVIDER_URI); - - // InputStream - InputStream in = getContentResolver().openInputStream(providerUri); - inLength = PgpHelper.getLengthOfStream(in); - inputData = new InputData(in, inLength); - - // OutputStream - try { - while (true) { - streamFilename = PgpHelper.generateRandomFilename(32); - if (streamFilename == null) { - throw new PgpGeneralException("couldn't generate random file name"); - } - openFileInput(streamFilename).close(); - } - } catch (FileNotFoundException e) { - // found a name that isn't used yet - } - outStream = openFileOutput(streamFilename, Context.MODE_PRIVATE); - - break; + // TODO: not used, maybe contains code useful for new decrypt method for files? +// case TARGET_STREAM: /* decrypting stream from content uri */ +// Uri providerUri = (Uri) data.getParcelable(ENCRYPT_PROVIDER_URI); +// +// // InputStream +// InputStream in = getContentResolver().openInputStream(providerUri); +// inLength = PgpHelper.getLengthOfStream(in); +// inputData = new InputData(in, inLength); +// +// // OutputStream +// try { +// while (true) { +// streamFilename = PgpHelper.generateRandomFilename(32); +// if (streamFilename == null) { +// throw new PgpGeneralException("couldn't generate random file name"); +// } +// openFileInput(streamFilename).close(); +// } +// } catch (FileNotFoundException e) { +// // found a name that isn't used yet +// } +// outStream = openFileOutput(streamFilename, Context.MODE_PRIVATE); +// +// break; default: throw new PgpGeneralException("No target choosen!"); @@ -486,11 +487,11 @@ public class KeychainIntentService extends IntentService // nothing, file was written, just send okay and verification bundle break; - case TARGET_STREAM: - String uri = DataStream.buildDataStreamUri(streamFilename).toString(); - resultData.putString(RESULT_URI, uri); - - break; +// case TARGET_STREAM: +// String uri = DataStream.buildDataStreamUri(streamFilename).toString(); +// resultData.putString(RESULT_URI, uri); +// +// break; } OtherHelper.logDebugBundle(resultData, "resultData"); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 2ffed07ff..3e153a71b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Dominik Schürmann + * Copyright (C) 2012-2014 Dominik Schürmann * Copyright (C) 2010 Thialfihar * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,45 +20,32 @@ package org.sufficientlysecure.keychain.ui; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.Messenger; -import android.support.v4.app.Fragment; import android.support.v4.view.PagerTabStrip; import android.support.v4.view.ViewPager; import android.view.View; import android.view.View.OnClickListener; -import android.widget.*; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; import com.beardedhen.androidbootstrap.BootstrapButton; import com.devspark.appmsg.AppMsg; import org.openintents.openpgp.OpenPgpSignatureResult; -import org.spongycastle.openpgp.PGPPublicKeyRing; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.helper.FileHelper; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.pgp.exception.NoAsymmetricEncryptionException; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.PassphraseCacheService; -import org.sufficientlysecure.keychain.ui.adapter.PageTabStripAdapter; -import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; -import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; +import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter; import org.sufficientlysecure.keychain.util.Log; -import java.io.*; import java.util.regex.Matcher; -//@SuppressLint("NewApi") public class DecryptActivity extends DrawerActivity implements DecryptSignatureResultDisplay { - /* Intents */ // without permission public static final String ACTION_DECRYPT = Constants.INTENT_PREFIX + "DECRYPT"; @@ -66,56 +53,24 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR /* EXTRA keys for input */ public static final String EXTRA_TEXT = "text"; - public static final String EXTRA_SELECTED_TAB = "selected_tab"; - private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006; - private static final int RESULT_CODE_FILE = 0x00007003; private long mSignatureKeyId = 0; -// private boolean mReturnResult = false; - - // TODO: replace signed only checks with something more intelligent - // PgpDecryptVerify should handle all automatically!!! - private boolean mSignedOnly = false; - private boolean mAssumeSymmetricEncryption = false; - - // private EditText mMessage = null; private RelativeLayout mSignatureLayout = null; private ImageView mSignatureStatusImage = null; private TextView mUserId = null; private TextView mUserIdRest = null; -// private ViewFlipper mSource = null; -// private TextView mSourceLabel = null; -// private ImageView mSourcePrevious = null; -// private ImageView mSourceNext = null; - - private int mDecryptTarget; - - private EditText mFilename = null; - private CheckBox mDeleteAfter = null; - private BootstrapButton mBrowse = null; private BootstrapButton mLookupKey = null; - private String mInputFilename = null; - private String mOutputFilename = null; - - private Uri mContentUri = null; - private boolean mReturnBinary = false; - - private long mSecretKeyId = Id.key.none; - - private FileDialogFragment mFileDialog; - -// private boolean mDecryptImmediately = false; - - private BootstrapButton mDecryptButton; - ViewPager mViewPager; PagerTabStrip mPagerTabStrip; - PageTabStripAdapter mTabsAdapter; + PagerTabStripAdapter mTabsAdapter; + Bundle mMessageFragmentBundle = new Bundle(); + Bundle mFileFragmentBundle = new Bundle(); + int mSwitchToTab = PAGER_TAB_MESSAGE; private static final int PAGER_TAB_MESSAGE = 0; private static final int PAGER_TAB_FILE = 1; @@ -126,75 +81,20 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR mSignatureStatusImage = (ImageView) findViewById(R.id.ic_signature_status); mUserId = (TextView) findViewById(R.id.mainUserId); mUserIdRest = (TextView) findViewById(R.id.mainUserIdRest); - - // measure the height of the source_file view and set the message view's min height to that, - // so it fills mSource fully... bit of a hack. -// View tmp = findViewById(R.id.sourceFile); -// tmp.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); -// int height = tmp.getMeasuredHeight(); -// mMessage.setMinimumHeight(height); - -// mFilename = (EditText) findViewById(R.id.filename); -// mBrowse = (BootstrapButton) findViewById(R.id.btn_browse); -// mBrowse.setOnClickListener(new View.OnClickListener() { -// public void onClick(View v) { -// FileHelper.openFile(DecryptActivity.this, mFilename.getText().toString(), "*/*", -// RESULT_CODE_FILE); -// } -// }); -// -// mLookupKey = (BootstrapButton) findViewById(R.id.lookup_key); -// mLookupKey.setOnClickListener(new OnClickListener() { -// @Override -// public void onClick(View v) { -// lookupUnknownKey(mSignatureKeyId); -// } -// }); -// -// mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterDecryption); - - // default: message source -// mSource.setInAnimation(null); -// mSource.setOutAnimation(null); -// while (mSource.getCurrentView().getId() != R.id.sourceMessage) { -// mSource.showNext(); -// } - -// mDecryptButton = (BootstrapButton) findViewById(R.id.action_decrypt); -// mDecryptButton.setOnClickListener(new OnClickListener() { -// @Override -// public void onClick(View v) { -// decryptClicked(); -// } -// }); - + mLookupKey = (BootstrapButton) findViewById(R.id.lookup_key); + mLookupKey.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + lookupUnknownKey(mSignatureKeyId); + } + }); // Pager mViewPager = (ViewPager) findViewById(R.id.decrypt_pager); mPagerTabStrip = (PagerTabStrip) findViewById(R.id.decrypt_pager_tab_strip); - mTabsAdapter = new PageTabStripAdapter(this); + mTabsAdapter = new PagerTabStripAdapter(this); mViewPager.setAdapter(mTabsAdapter); - - Bundle messageBundle = new Bundle(); - mTabsAdapter.addTab(DecryptMessageFragment.class, messageBundle, getString(R.string.label_message)); - - Bundle fileBundle = new Bundle(); - mTabsAdapter.addTab(DecryptFileFragment.class, fileBundle, getString(R.string.label_file)); - } - - - /** - * find fragment - * - * @param pos - * @return - */ - public Fragment getFragmentByPosition(int pos) { - // based on FragmentPagerAdapter.makeFragmentName() - String tag = "android:switcher:" + mViewPager.getId() + ":" + pos; - Log.d(Constants.TAG, "findFragmentByTag: "+tag); - return getSupportFragmentManager().findFragmentByTag(tag); } @Override @@ -210,23 +110,17 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR setupDrawerNavigation(savedInstanceState); - // Handle intent actions + // Handle intent actions, maybe changes the bundles handleActions(getIntent()); + mTabsAdapter.addTab(DecryptMessageFragment.class, mMessageFragmentBundle, getString(R.string.label_message)); + mTabsAdapter.addTab(DecryptFileFragment.class, mFileFragmentBundle, getString(R.string.label_file)); + mViewPager.setCurrentItem(mSwitchToTab); + mSignatureLayout.setVisibility(View.GONE); mSignatureLayout.setOnClickListener(new OnClickListener() { public void onClick(View v) { - if (mSignatureKeyId == 0) { - return; - } - PGPPublicKeyRing key = ProviderHelper.getPGPPublicKeyRingByKeyId( - DecryptActivity.this, mSignatureKeyId); - if (key != null) { - Intent intent = new Intent(DecryptActivity.this, ImportKeysActivity.class); - intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER); - intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, mSignatureKeyId); - startActivity(intent); - } + lookupUnknownKey(mSignatureKeyId); } }); } @@ -288,9 +182,8 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR // replace non breakable spaces textData = textData.replaceAll("\\xa0", " "); -// mViewPager.setCurrentItem(PAGER_TAB_MESSAGE, false); -// mMessageFragment.setText(textData); -// mMessage.setText(textData); + mMessageFragmentBundle.putString(DecryptMessageFragment.ARG_CIPHERTEXT, textData); + mSwitchToTab = PAGER_TAB_MESSAGE; } else { matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(textData); if (matcher.matches()) { @@ -298,10 +191,9 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR textData = matcher.group(1); // replace non breakable spaces textData = textData.replaceAll("\\xa0", " "); -// mMessage.setText(textData); -// mViewPager.setCurrentItem(PAGER_TAB_MESSAGE, false); -// mMessageFragment = (DecryptMessageFragment) getFragmentByPosition(mViewPager.getCurrentItem()); -// mMessageFragment.setText(textData); + + mMessageFragmentBundle.putString(DecryptMessageFragment.ARG_CIPHERTEXT, textData); + mSwitchToTab = PAGER_TAB_MESSAGE; } else { Log.d(Constants.TAG, "Nothing matched!"); } @@ -311,14 +203,8 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR String path = FileHelper.getPath(this, uri); if (path != null) { - mInputFilename = path; - mFilename.setText(mInputFilename); -// guessOutputFilename(); -// mSource.setInAnimation(null); -// mSource.setOutAnimation(null); -// while (mSource.getCurrentView().getId() != R.id.sourceFile) { -// mSource.showNext(); -// } + mFileFragmentBundle.putString(DecryptFileFragment.ARG_FILENAME, path); + mSwitchToTab = PAGER_TAB_FILE; } else { Log.e(Constants.TAG, "Direct binary data without actual file in filesystem is not supported. Please use the Remote Service API!"); @@ -333,198 +219,6 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR } } -// private void guessOutputFilename() { -// mInputFilename = mFilename.getText().toString(); -// File file = new File(mInputFilename); -// String filename = file.getName(); -// if (filename.endsWith(".asc") || filename.endsWith(".gpg") || filename.endsWith(".pgp")) { -// filename = filename.substring(0, filename.length() - 4); -// } -// mOutputFilename = Constants.Path.APP_DIR + "/" + filename; -// } - - private void decryptClicked() { - if (mViewPager.getCurrentItem() == PAGER_TAB_FILE) { - mDecryptTarget = Id.target.file; - } else { - mDecryptTarget = Id.target.message; - } - initiateDecryption(); - } - - private void initiateDecryption() { - if (mDecryptTarget == Id.target.file) { - String currentFilename = mFilename.getText().toString(); - if (mInputFilename == null || !mInputFilename.equals(currentFilename)) { -// guessOutputFilename(); - } - - if (mInputFilename.equals("")) { - AppMsg.makeText(this, R.string.no_file_selected, AppMsg.STYLE_ALERT).show(); - return; - } - - if (mInputFilename.startsWith("file")) { - File file = new File(mInputFilename); - if (!file.exists() || !file.isFile()) { - AppMsg.makeText( - this, - getString(R.string.error_message, - getString(R.string.error_file_not_found)), AppMsg.STYLE_ALERT) - .show(); - return; - } - } - } - - if (mDecryptTarget == Id.target.message) { -// String messageData = mMessage.getText().toString(); -// Matcher matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(messageData); -// if (matcher.matches()) { -// mSignedOnly = true; -// decryptStart(); -// return; -// } - } - - // else treat it as an decrypted message/file - mSignedOnly = false; - - getDecryptionKeyFromInputStream(); - - // if we need a symmetric passphrase or a passphrase to use a secret key ask for it - if (mAssumeSymmetricEncryption || PassphraseCacheService.getCachedPassphrase(this, mSecretKeyId) == null) { - showPassphraseDialog(); - } else { - if (mDecryptTarget == Id.target.file) { - askForOutputFilename(); - } else { // mDecryptTarget == Id.target.message -// decryptStart(); - } - } - } - - /** - * Shows passphrase dialog to cache a new passphrase the user enters for using it later for - * encryption. Based on mSecretKeyId it asks for a passphrase to open a private key or it asks - * for a symmetric passphrase - */ - private void showPassphraseDialog() { - // Message is received after passphrase is cached - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - if (mDecryptTarget == Id.target.file) { - askForOutputFilename(); - } else { -// decryptStart(); - } - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - try { - PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(this, - messenger, mSecretKeyId); - - passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); - } catch (PgpGeneralException e) { - Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); - // send message to handler to start encryption directly - returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); - } - } - - /** - * TODO: Rework function, remove global variables - */ - private void getDecryptionKeyFromInputStream() { - mAssumeSymmetricEncryption = false; - InputStream inStream = null; - if (mContentUri != null) { - try { - inStream = getContentResolver().openInputStream(mContentUri); - } catch (FileNotFoundException e) { - Log.e(Constants.TAG, "File not found!", e); - AppMsg.makeText(this, getString(R.string.error_file_not_found, e.getMessage()), - AppMsg.STYLE_ALERT).show(); - } - } else if (mDecryptTarget == Id.target.file) { - // check if storage is ready - if (!FileHelper.isStorageMounted(mInputFilename)) { - AppMsg.makeText(this, getString(R.string.error_external_storage_not_ready), - AppMsg.STYLE_ALERT).show(); - return; - } - - try { - inStream = new BufferedInputStream(new FileInputStream(mInputFilename)); - } catch (FileNotFoundException e) { - Log.e(Constants.TAG, "File not found!", e); - AppMsg.makeText(this, getString(R.string.error_file_not_found, e.getMessage()), - AppMsg.STYLE_ALERT).show(); - } - } else { - -// inStream = new ByteArrayInputStream(mMessage.getText().toString().getBytes()); - } - - // get decryption key for this inStream - try { - try { - if (inStream.markSupported()) { - inStream.mark(200); // should probably set this to the max size of two pgpF - // objects, if it even needs to be anything other than 0. - } - mSecretKeyId = PgpHelper.getDecryptionKeyId(this, inStream); - if (mSecretKeyId == Id.key.none) { - throw new PgpGeneralException(getString(R.string.error_no_secret_key_found)); - } - } catch (NoAsymmetricEncryptionException e) { - if (inStream.markSupported()) { - inStream.reset(); - } - mSecretKeyId = Id.key.symmetric; - if (!PgpDecryptVerify.hasSymmetricEncryption(this, inStream)) { - throw new PgpGeneralException( - getString(R.string.error_no_known_encryption_found)); - } - mAssumeSymmetricEncryption = true; - } - } catch (Exception e) { - Log.e(Constants.TAG, "error while reading decryption key from input stream", e); - AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()), - AppMsg.STYLE_ALERT).show(); - } - } - - private void askForOutputFilename() { - // Message is received after passphrase is cached - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == FileDialogFragment.MESSAGE_OKAY) { - Bundle data = message.getData(); - mOutputFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); -// decryptStart(); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - mFileDialog = FileDialogFragment.newInstance(messenger, - getString(R.string.title_decrypt_to_file), - getString(R.string.specify_file_to_decrypt_to), mOutputFilename, null); - - mFileDialog.show(getSupportFragmentManager(), "fileDialog"); - } - private void lookupUnknownKey(long unknownKeyId) { Intent intent = new Intent(this, ImportKeysActivity.class); intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER); @@ -532,173 +226,9 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR startActivityForResult(intent, RESULT_CODE_LOOKUP_KEY); } -// private void decryptStart() { -// Log.d(Constants.TAG, "decryptStart"); -// -// // Send all information needed to service to decrypt in other thread -// Intent intent = new Intent(this, KeychainIntentService.class); -// -// // fill values for this action -// Bundle data = new Bundle(); -// -// intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY); -// -// // choose action based on input: decrypt stream, file or bytes -// if (mContentUri != null) { -// data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_STREAM); -// -// data.putParcelable(KeychainIntentService.ENCRYPT_PROVIDER_URI, mContentUri); -// } else if (mDecryptTarget == Id.target.file) { -// data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI); -// -// Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" -// + mOutputFilename); -// -// data.putString(KeychainIntentService.ENCRYPT_INPUT_FILE, mInputFilename); -// data.putString(KeychainIntentService.ENCRYPT_OUTPUT_FILE, mOutputFilename); -// } else { -// data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); -// -//// String message = mMessage.getText().toString(); -//// data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, message.getBytes()); -// } -// -// data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyId); -// -// data.putBoolean(KeychainIntentService.DECRYPT_RETURN_BYTES, mReturnBinary); -// data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, mAssumeSymmetricEncryption); -// -// intent.putExtra(KeychainIntentService.EXTRA_DATA, data); -// -// // Message is received after encrypting is done in KeychainIntentService -// KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, -// getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) { -// public void handleMessage(Message message) { -// // handle messages by standard KeychainIntentServiceHandler first -// super.handleMessage(message); -// -// if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { -// // get returned data bundle -// Bundle returnData = message.getData(); -// -// mSignatureKeyId = 0; -// mSignatureLayout.setVisibility(View.GONE); -// -// AppMsg.makeText(DecryptActivity.this, R.string.decryption_successful, -// AppMsg.STYLE_INFO).show(); -//// if (mReturnResult) { -//// Intent intent = new Intent(); -//// intent.putExtras(returnData); -//// setResult(RESULT_OK, intent); -//// finish(); -//// return; -//// } -// -// switch (mDecryptTarget) { -// case Id.target.message: -// String decryptedMessage = returnData -// .getString(KeychainIntentService.RESULT_DECRYPTED_STRING); -//// mMessage.setText(decryptedMessage); -//// mMessage.setHorizontallyScrolling(false); -// -// break; -// -// case Id.target.file: -// if (mDeleteAfter.isChecked()) { -// // Create and show dialog to delete original file -// DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment -// .newInstance(mInputFilename); -// deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); -// } -// break; -// -// default: -// // shouldn't happen -// break; -// -// } -// -// PgpDecryptVerifyResult decryptVerifyResult = -// returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT); -// -// OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); -// -// if (signatureResult != null) { -// -// String userId = signatureResult.getUserId(); -// mSignatureKeyId = signatureResult.getKeyId(); -// mUserIdRest.setText("id: " -// + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId)); -// if (userId == null) { -// userId = getResources().getString(R.string.user_id_no_name); -// } -// String chunks[] = userId.split(" <", 2); -// userId = chunks[0]; -// if (chunks.length > 1) { -// mUserIdRest.setText("<" + chunks[1]); -// } -// mUserId.setText(userId); -// -// switch (signatureResult.getStatus()) { -// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { -// mSignatureStatusImage.setImageResource(R.drawable.overlay_ok); -// mLookupKey.setVisibility(View.GONE); -// break; -// } -// -// // TODO! -//// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { -//// break; -//// } -// -// case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: { -// mSignatureStatusImage.setImageResource(R.drawable.overlay_error); -// mLookupKey.setVisibility(View.VISIBLE); -// AppMsg.makeText(DecryptActivity.this, -// R.string.unknown_signature, -// AppMsg.STYLE_ALERT).show(); -// break; -// } -// -// default: { -// mSignatureStatusImage.setImageResource(R.drawable.overlay_error); -// mLookupKey.setVisibility(View.GONE); -// break; -// } -// } -// mSignatureLayout.setVisibility(View.VISIBLE); -// } -// } -// } -// }; -// -// // Create a new Messenger for the communication back -// Messenger messenger = new Messenger(saveHandler); -// intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); -// -// // show progress dialog -// saveHandler.showProgressDialog(this); -// -// // start service with intent -// startService(intent); -// } - @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { - case RESULT_CODE_FILE: { - if (resultCode == RESULT_OK && data != null) { - try { - String path = FileHelper.getPath(this, data.getData()); - Log.d(Constants.TAG, "path=" + path); - - mFilename.setText(path); - } catch (NullPointerException e) { - Log.e(Constants.TAG, "Nullpointer while retrieving path!"); - } - } - return; - } // this request is returned after LookupUnknownKeyDialogFragment started // ImportKeysActivity and user looked uo key @@ -721,24 +251,25 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR @Override public void onSignatureResult(OpenPgpSignatureResult signatureResult) { - mSignatureKeyId = 0; mSignatureLayout.setVisibility(View.GONE); if (signatureResult != null) { - String userId = signatureResult.getUserId(); mSignatureKeyId = signatureResult.getKeyId(); - mUserIdRest.setText("id: " - + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId)); - if (userId == null) { - userId = getResources().getString(R.string.user_id_no_name); + + String userId = signatureResult.getUserId(); + String[] userIdSplit = PgpKeyHelper.splitUserId(userId); + if (userIdSplit[0] != null) { + mUserId.setText(userId); + } else { + mUserId.setText(R.string.user_id_no_name); } - String chunks[] = userId.split(" <", 2); - userId = chunks[0]; - if (chunks.length > 1) { - mUserIdRest.setText("<" + chunks[1]); + if (userIdSplit[1] != null) { + mUserIdRest.setText(userIdSplit[1]); + } else { + mUserIdRest.setText(getString(R.string.label_key_id) + ": " + + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId)); } - mUserId.setText(userId); switch (signatureResult.getStatus()) { case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index 6646be8ee..cef960df2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -17,6 +17,9 @@ package org.sufficientlysecure.keychain.ui; +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -31,14 +34,25 @@ import android.widget.EditText; import com.beardedhen.androidbootstrap.BootstrapButton; import com.devspark.appmsg.AppMsg; +import org.openintents.openpgp.OpenPgpSignatureResult; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.FileHelper; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; +import org.sufficientlysecure.keychain.util.Log; import java.io.File; public class DecryptFileFragment extends Fragment { + public static final String ARG_FILENAME = "filename"; + + DecryptSignatureResultDisplay mSignatureResultDisplay; private EditText mFilename; private CheckBox mDeleteAfter; @@ -54,18 +68,6 @@ public class DecryptFileFragment extends Fragment { private static final int RESULT_CODE_FILE = 0x00007003; - /** - * Creates new instance of this fragment - */ - public static DecryptFileFragment newInstance() { - DecryptFileFragment frag = new DecryptFileFragment(); - - Bundle args = new Bundle(); - frag.setArguments(args); - - return frag; - } - /** * Inflate the layout for this fragment */ @@ -73,16 +75,16 @@ public class DecryptFileFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.decrypt_file_fragment, container, false); - mFilename = (EditText) view.findViewById(R.id.filename); - mBrowse = (BootstrapButton) view.findViewById(R.id.btn_browse); + mFilename = (EditText) view.findViewById(R.id.decrypt_file_filename); + mBrowse = (BootstrapButton) view.findViewById(R.id.decrypt_file_browse); mBrowse.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - FileHelper.openFile(getActivity(), mFilename.getText().toString(), "*/*", + FileHelper.openFile(DecryptFileFragment.this, mFilename.getText().toString(), "*/*", RESULT_CODE_FILE); } }); - mDeleteAfter = (CheckBox) view.findViewById(R.id.deleteAfterDecryption); - mDecryptButton = (BootstrapButton) view.findViewById(R.id.action_decrypt); + mDeleteAfter = (CheckBox) view.findViewById(R.id.decrypt_file_delete_after_decryption); + mDecryptButton = (BootstrapButton) view.findViewById(R.id.decrypt_file_action_decrypt); mDecryptButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -90,9 +92,24 @@ public class DecryptFileFragment extends Fragment { } }); + String filename = getArguments().getString(ARG_FILENAME); + if (filename != null) { + mFilename.setText(filename); + } + return view; } + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + mSignatureResultDisplay = (DecryptSignatureResultDisplay) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + " must implement DecryptSignatureResultDisplay"); + } + } + private void guessOutputFilename() { mInputFilename = mFilename.getText().toString(); File file = new File(mInputFilename); @@ -142,7 +159,7 @@ public class DecryptFileFragment extends Fragment { if (message.what == FileDialogFragment.MESSAGE_OKAY) { Bundle data = message.getData(); mOutputFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); -// decryptStart(); + decryptStart(null); } } }; @@ -157,4 +174,131 @@ public class DecryptFileFragment extends Fragment { mFileDialog.show(getActivity().getSupportFragmentManager(), "fileDialog"); } + private void decryptStart(String passphrase) { + Log.d(Constants.TAG, "decryptStart"); + + // Send all information needed to service to decrypt in other thread + Intent intent = new Intent(getActivity(), KeychainIntentService.class); + + // fill values for this action + Bundle data = new Bundle(); + + intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY); + + // data + data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI); + + Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" + + mOutputFilename); + + data.putString(KeychainIntentService.ENCRYPT_INPUT_FILE, mInputFilename); + data.putString(KeychainIntentService.ENCRYPT_OUTPUT_FILE, mOutputFilename); + + data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, passphrase); + + // TODO + data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, false); + + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Message is received after encrypting is done in KeychainIntentService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(), + getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle returnData = message.getData(); + + + PgpDecryptVerifyResult decryptVerifyResult = + returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT); + + if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { + showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded()); + } else { + + if (mDeleteAfter.isChecked()) { + // Create and show dialog to delete original file + DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment + .newInstance(mInputFilename); + deleteFileDialog.show(getActivity().getSupportFragmentManager(), "deleteDialog"); + } + + + OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); + + // display signature result in activity + mSignatureResultDisplay.onSignatureResult(signatureResult); + } + + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(getActivity()); + + // start service with intent + getActivity().startService(intent); + } + + private void showPassphraseDialog(long keyId) { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + String passphrase = + message.getData().getString(PassphraseDialogFragment.MESSAGE_DATA_PASSPHRASE); + decryptStart(passphrase); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + try { + PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(getActivity(), + messenger, keyId); + + passphraseDialog.show(getActivity().getSupportFragmentManager(), "passphraseDialog"); + } catch (PgpGeneralException e) { + Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); + // send message to handler to start encryption directly + returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case RESULT_CODE_FILE: { + if (resultCode == Activity.RESULT_OK && data != null) { + try { + String path = FileHelper.getPath(getActivity(), data.getData()); + Log.d(Constants.TAG, "path=" + path); + + mFilename.setText(path); + } catch (NullPointerException e) { + Log.e(Constants.TAG, "Nullpointer while retrieving path!"); + } + } + return; + } + + default: { + super.onActivityResult(requestCode, resultCode, data); + + break; + } + } + } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java index c6724f6d1..a50f080ab 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java @@ -49,13 +49,14 @@ import org.sufficientlysecure.keychain.util.Log; import java.util.regex.Matcher; public class DecryptMessageFragment extends Fragment { + public static final String ARG_CIPHERTEXT = "ciphertext"; + DecryptSignatureResultDisplay mSignatureResultDisplay; private EditText mMessage; private BootstrapButton mDecryptButton; private BootstrapButton mDecryptFromCLipboardButton; - public static final String EXTRA_CIPHERTEXT = "ciphertext"; /** * Inflate the layout for this fragment @@ -68,11 +69,6 @@ public class DecryptMessageFragment extends Fragment { mDecryptButton = (BootstrapButton) view.findViewById(R.id.action_decrypt); mDecryptFromCLipboardButton = (BootstrapButton) view.findViewById(R.id.action_decrypt_from_clipboard); - String ciphertext = getArguments().getString(EXTRA_CIPHERTEXT); - if (ciphertext != null) { - mMessage.setText(ciphertext); - } - mDecryptButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -105,9 +101,11 @@ public class DecryptMessageFragment extends Fragment { public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - Log.d(Constants.TAG, "onActivityCreated tag: " + getTag()); - - + String ciphertext = getArguments().getString(ARG_CIPHERTEXT); + if (ciphertext != null) { + mMessage.setText(ciphertext); + decryptStart(null); + } } private void decryptFromClipboard() { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PageTabStripAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PageTabStripAdapter.java deleted file mode 100644 index 402699623..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PageTabStripAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.ui.adapter; - -import android.content.Context; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentPagerAdapter; -import android.support.v4.app.FragmentStatePagerAdapter; -import android.support.v4.app.FragmentTransaction; -import android.support.v4.view.ViewPager; -import android.support.v7.app.ActionBar; -import android.support.v7.app.ActionBarActivity; - -import java.util.ArrayList; - -public class PageTabStripAdapter extends FragmentPagerAdapter { - private final Context mContext; - private final ArrayList mTabs = new ArrayList(); - - static final class TabInfo { - private final Class clss; - private final Bundle args; - private final String title; - - TabInfo(Class clss, Bundle args, String title) { - this.clss = clss; - this.args = args; - this.title = title; - } - } - - public PageTabStripAdapter(ActionBarActivity activity) { - super(activity.getSupportFragmentManager()); - mContext = activity; - } - - public void addTab(Class clss, Bundle args, String title) { - TabInfo info = new TabInfo(clss, args, title); - mTabs.add(info); - notifyDataSetChanged(); - } - - @Override - public int getCount() { - return mTabs.size(); - } - - @Override - public Fragment getItem(int position) { - TabInfo info = mTabs.get(position); - return Fragment.instantiate(mContext, info.clss.getName(), info.args); - } - - @Override - public CharSequence getPageTitle(int position) { - return mTabs.get(position).title; - } -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java new file mode 100644 index 000000000..3e7952beb --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.ui.adapter; + +import android.content.Context; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.app.FragmentTransaction; +import android.support.v4.view.ViewPager; +import android.support.v7.app.ActionBar; +import android.support.v7.app.ActionBarActivity; + +import java.util.ArrayList; + +public class PagerTabStripAdapter extends FragmentPagerAdapter { + private final Context mContext; + private final ArrayList mTabs = new ArrayList(); + + static final class TabInfo { + private final Class clss; + private final Bundle args; + private final String title; + + TabInfo(Class clss, Bundle args, String title) { + this.clss = clss; + this.args = args; + this.title = title; + } + } + + public PagerTabStripAdapter(ActionBarActivity activity) { + super(activity.getSupportFragmentManager()); + mContext = activity; + } + + public void addTab(Class clss, Bundle args, String title) { + TabInfo info = new TabInfo(clss, args, title); + mTabs.add(info); + notifyDataSetChanged(); + } + + @Override + public int getCount() { + return mTabs.size(); + } + + @Override + public Fragment getItem(int position) { + TabInfo info = mTabs.get(position); + return Fragment.instantiate(mContext, info.clss.getName(), info.args); + } + + @Override + public CharSequence getPageTitle(int position) { + return mTabs.get(position).title; + } +} -- cgit v1.2.3 From bb2fb786a8583ecc0366021e2d748e3d39891407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 30 Mar 2014 21:33:00 +0200 Subject: Include signature result in fragments --- .../keychain/ui/DecryptActivity.java | 114 +----------- .../keychain/ui/DecryptFileFragment.java | 55 +----- .../keychain/ui/DecryptFragment.java | 194 +++++++++++++++++++++ .../keychain/ui/DecryptMessageFragment.java | 59 +------ .../keychain/ui/DecryptSignatureResultDisplay.java | 27 --- 5 files changed, 204 insertions(+), 245 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptSignatureResultDisplay.java (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 3e153a71b..d6dad424e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -44,7 +44,7 @@ import org.sufficientlysecure.keychain.util.Log; import java.util.regex.Matcher; -public class DecryptActivity extends DrawerActivity implements DecryptSignatureResultDisplay { +public class DecryptActivity extends DrawerActivity { /* Intents */ // without permission @@ -53,17 +53,6 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR /* EXTRA keys for input */ public static final String EXTRA_TEXT = "text"; - private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006; - - private long mSignatureKeyId = 0; - - private RelativeLayout mSignatureLayout = null; - private ImageView mSignatureStatusImage = null; - private TextView mUserId = null; - private TextView mUserIdRest = null; - - private BootstrapButton mLookupKey = null; - ViewPager mViewPager; PagerTabStrip mPagerTabStrip; PagerTabStripAdapter mTabsAdapter; @@ -77,18 +66,6 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR private void initView() { - mSignatureLayout = (RelativeLayout) findViewById(R.id.signature); - mSignatureStatusImage = (ImageView) findViewById(R.id.ic_signature_status); - mUserId = (TextView) findViewById(R.id.mainUserId); - mUserIdRest = (TextView) findViewById(R.id.mainUserIdRest); - mLookupKey = (BootstrapButton) findViewById(R.id.lookup_key); - mLookupKey.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - lookupUnknownKey(mSignatureKeyId); - } - }); - // Pager mViewPager = (ViewPager) findViewById(R.id.decrypt_pager); mPagerTabStrip = (PagerTabStrip) findViewById(R.id.decrypt_pager_tab_strip); @@ -116,13 +93,6 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR mTabsAdapter.addTab(DecryptMessageFragment.class, mMessageFragmentBundle, getString(R.string.label_message)); mTabsAdapter.addTab(DecryptFileFragment.class, mFileFragmentBundle, getString(R.string.label_file)); mViewPager.setCurrentItem(mSwitchToTab); - - mSignatureLayout.setVisibility(View.GONE); - mSignatureLayout.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - lookupUnknownKey(mSignatureKeyId); - } - }); } @@ -219,86 +189,4 @@ public class DecryptActivity extends DrawerActivity implements DecryptSignatureR } } - private void lookupUnknownKey(long unknownKeyId) { - Intent intent = new Intent(this, ImportKeysActivity.class); - intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER); - intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, unknownKeyId); - startActivityForResult(intent, RESULT_CODE_LOOKUP_KEY); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - - // this request is returned after LookupUnknownKeyDialogFragment started - // ImportKeysActivity and user looked uo key - case RESULT_CODE_LOOKUP_KEY: { - Log.d(Constants.TAG, "Returning from Lookup Key..."); - if (resultCode == RESULT_OK) { - // decrypt again -// decryptStart(); - } - return; - } - - default: { - super.onActivityResult(requestCode, resultCode, data); - - break; - } - } - } - - @Override - public void onSignatureResult(OpenPgpSignatureResult signatureResult) { - mSignatureKeyId = 0; - mSignatureLayout.setVisibility(View.GONE); - if (signatureResult != null) { - - mSignatureKeyId = signatureResult.getKeyId(); - - String userId = signatureResult.getUserId(); - String[] userIdSplit = PgpKeyHelper.splitUserId(userId); - if (userIdSplit[0] != null) { - mUserId.setText(userId); - } else { - mUserId.setText(R.string.user_id_no_name); - } - if (userIdSplit[1] != null) { - mUserIdRest.setText(userIdSplit[1]); - } else { - mUserIdRest.setText(getString(R.string.label_key_id) + ": " - + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId)); - } - - switch (signatureResult.getStatus()) { - case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { - mSignatureStatusImage.setImageResource(R.drawable.overlay_ok); - mLookupKey.setVisibility(View.GONE); - break; - } - - // TODO! -// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { -// break; -// } - - case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: { - mSignatureStatusImage.setImageResource(R.drawable.overlay_error); - mLookupKey.setVisibility(View.VISIBLE); - AppMsg.makeText(DecryptActivity.this, - R.string.unknown_signature, - AppMsg.STYLE_ALERT).show(); - break; - } - - default: { - mSignatureStatusImage.setImageResource(R.drawable.overlay_error); - mLookupKey.setVisibility(View.GONE); - break; - } - } - mSignatureLayout.setVisibility(View.VISIBLE); - } - } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index cef960df2..069a5a584 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -24,7 +24,6 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Messenger; -import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -39,21 +38,17 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; -import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; import java.io.File; -public class DecryptFileFragment extends Fragment { +public class DecryptFileFragment extends DecryptFragment { public static final String ARG_FILENAME = "filename"; - DecryptSignatureResultDisplay mSignatureResultDisplay; - private EditText mFilename; private CheckBox mDeleteAfter; private BootstrapButton mBrowse; @@ -100,16 +95,6 @@ public class DecryptFileFragment extends Fragment { return view; } - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - try { - mSignatureResultDisplay = (DecryptSignatureResultDisplay) activity; - } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() + " must implement DecryptSignatureResultDisplay"); - } - } - private void guessOutputFilename() { mInputFilename = mFilename.getText().toString(); File file = new File(mInputFilename); @@ -120,11 +105,6 @@ public class DecryptFileFragment extends Fragment { mOutputFilename = Constants.Path.APP_DIR + "/" + filename; } - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - } - private void decryptAction() { String currentFilename = mFilename.getText().toString(); if (mInputFilename == null || !mInputFilename.equals(currentFilename)) { @@ -174,7 +154,8 @@ public class DecryptFileFragment extends Fragment { mFileDialog.show(getActivity().getSupportFragmentManager(), "fileDialog"); } - private void decryptStart(String passphrase) { + @Override + protected void decryptStart(String passphrase) { Log.d(Constants.TAG, "decryptStart"); // Send all information needed to service to decrypt in other thread @@ -231,7 +212,7 @@ public class DecryptFileFragment extends Fragment { OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); // display signature result in activity - mSignatureResultDisplay.onSignatureResult(signatureResult); + onSignatureResult(signatureResult); } } @@ -249,34 +230,6 @@ public class DecryptFileFragment extends Fragment { getActivity().startService(intent); } - private void showPassphraseDialog(long keyId) { - // Message is received after passphrase is cached - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - String passphrase = - message.getData().getString(PassphraseDialogFragment.MESSAGE_DATA_PASSPHRASE); - decryptStart(passphrase); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - try { - PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(getActivity(), - messenger, keyId); - - passphraseDialog.show(getActivity().getSupportFragmentManager(), "passphraseDialog"); - } catch (PgpGeneralException e) { - Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); - // send message to handler to start encryption directly - returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); - } - } - @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java new file mode 100644 index 000000000..4c0c80742 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; +import android.support.v4.app.Fragment; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import com.beardedhen.androidbootstrap.BootstrapButton; +import com.devspark.appmsg.AppMsg; + +import org.openintents.openpgp.OpenPgpSignatureResult; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; +import org.sufficientlysecure.keychain.util.Log; + +public class DecryptFragment extends Fragment { + private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006; + + protected long mSignatureKeyId = 0; + + protected RelativeLayout mSignatureLayout = null; + protected ImageView mSignatureStatusImage = null; + protected TextView mUserId = null; + protected TextView mUserIdRest = null; + + protected BootstrapButton mLookupKey = null; + + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mSignatureLayout = (RelativeLayout) getView().findViewById(R.id.signature); + mSignatureStatusImage = (ImageView) getView().findViewById(R.id.ic_signature_status); + mUserId = (TextView) getView().findViewById(R.id.mainUserId); + mUserIdRest = (TextView) getView().findViewById(R.id.mainUserIdRest); + mLookupKey = (BootstrapButton) getView().findViewById(R.id.lookup_key); + mLookupKey.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + lookupUnknownKey(mSignatureKeyId); + } + }); + mSignatureLayout.setVisibility(View.GONE); + mSignatureLayout.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + lookupUnknownKey(mSignatureKeyId); + } + }); + } + + private void lookupUnknownKey(long unknownKeyId) { + Intent intent = new Intent(getActivity(), ImportKeysActivity.class); + intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER); + intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, unknownKeyId); + startActivityForResult(intent, RESULT_CODE_LOOKUP_KEY); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + + // this request is returned after LookupUnknownKeyDialogFragment started + // ImportKeysActivity and user looked uo key + case RESULT_CODE_LOOKUP_KEY: { + Log.d(Constants.TAG, "Returning from Lookup Key..."); + if (resultCode == Activity.RESULT_OK) { + // decrypt again +// decryptStart(); + } + return; + } + + default: { + super.onActivityResult(requestCode, resultCode, data); + + break; + } + } + } + + protected void onSignatureResult(OpenPgpSignatureResult signatureResult) { + mSignatureKeyId = 0; + mSignatureLayout.setVisibility(View.GONE); + if (signatureResult != null) { + + mSignatureKeyId = signatureResult.getKeyId(); + + String userId = signatureResult.getUserId(); + String[] userIdSplit = PgpKeyHelper.splitUserId(userId); + if (userIdSplit[0] != null) { + mUserId.setText(userId); + } else { + mUserId.setText(R.string.user_id_no_name); + } + if (userIdSplit[1] != null) { + mUserIdRest.setText(userIdSplit[1]); + } else { + mUserIdRest.setText(getString(R.string.label_key_id) + ": " + + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId)); + } + + switch (signatureResult.getStatus()) { + case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { + mSignatureStatusImage.setImageResource(R.drawable.overlay_ok); + mLookupKey.setVisibility(View.GONE); + break; + } + + // TODO! +// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { +// break; +// } + + case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: { + mSignatureStatusImage.setImageResource(R.drawable.overlay_error); + mLookupKey.setVisibility(View.VISIBLE); + AppMsg.makeText(getActivity(), + R.string.unknown_signature, + AppMsg.STYLE_ALERT).show(); + break; + } + + default: { + mSignatureStatusImage.setImageResource(R.drawable.overlay_error); + mLookupKey.setVisibility(View.GONE); + break; + } + } + mSignatureLayout.setVisibility(View.VISIBLE); + } + } + + protected void showPassphraseDialog(long keyId) { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + String passphrase = + message.getData().getString(PassphraseDialogFragment.MESSAGE_DATA_PASSPHRASE); + decryptStart(passphrase); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + try { + PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(getActivity(), + messenger, keyId); + + passphraseDialog.show(getActivity().getSupportFragmentManager(), "passphraseDialog"); + } catch (PgpGeneralException e) { + Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); + // send message to handler to start encryption directly + returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); + } + } + + protected void decryptStart(String passphrase) { + + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java index a50f080ab..3a8aaec42 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java @@ -17,14 +17,11 @@ package org.sufficientlysecure.keychain.ui; -import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; -import android.os.Handler; import android.os.Message; import android.os.Messenger; -import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -40,19 +37,15 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; import org.sufficientlysecure.keychain.pgp.PgpHelper; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; -import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; import java.util.regex.Matcher; -public class DecryptMessageFragment extends Fragment { +public class DecryptMessageFragment extends DecryptFragment { public static final String ARG_CIPHERTEXT = "ciphertext"; - DecryptSignatureResultDisplay mSignatureResultDisplay; - private EditText mMessage; private BootstrapButton mDecryptButton; private BootstrapButton mDecryptFromCLipboardButton; @@ -72,7 +65,7 @@ public class DecryptMessageFragment extends Fragment { mDecryptButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - decryptAction(); + decryptStart(null); } }); @@ -86,17 +79,6 @@ public class DecryptMessageFragment extends Fragment { return view; } - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - try { - mSignatureResultDisplay = (DecryptSignatureResultDisplay) activity; - } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() + " must implement DecryptSignatureResultDisplay"); - } - } - - @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); @@ -130,11 +112,8 @@ public class DecryptMessageFragment extends Fragment { } } - private void decryptAction() { - decryptStart(null); - } - - private void decryptStart(String passphrase) { + @Override + protected void decryptStart(String passphrase) { Log.d(Constants.TAG, "decryptStart"); // Send all information needed to service to decrypt in other thread @@ -187,7 +166,7 @@ public class DecryptMessageFragment extends Fragment { OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); // display signature result in activity - mSignatureResultDisplay.onSignatureResult(signatureResult); + onSignatureResult(signatureResult); } } @@ -205,33 +184,5 @@ public class DecryptMessageFragment extends Fragment { getActivity().startService(intent); } - private void showPassphraseDialog(long keyId) { - // Message is received after passphrase is cached - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - String passphrase = - message.getData().getString(PassphraseDialogFragment.MESSAGE_DATA_PASSPHRASE); - decryptStart(passphrase); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - try { - PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(getActivity(), - messenger, keyId); - - passphraseDialog.show(getActivity().getSupportFragmentManager(), "passphraseDialog"); - } catch (PgpGeneralException e) { - Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); - // send message to handler to start encryption directly - returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); - } - } - } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptSignatureResultDisplay.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptSignatureResultDisplay.java deleted file mode 100644 index e167064ec..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptSignatureResultDisplay.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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, see . - */ - -package org.sufficientlysecure.keychain.ui; - -import org.openintents.openpgp.OpenPgpSignatureResult; - -public interface DecryptSignatureResultDisplay { - - public void onSignatureResult(OpenPgpSignatureResult result); - -} - -- cgit v1.2.3 From 47b23a90d5bf395685ae4bdb75ae74f3047a02ab Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Mon, 31 Mar 2014 22:42:24 +0100 Subject: change how new default keys are passed back, fix showing their usage flags --- .../keychain/service/KeychainIntentService.java | 15 ++++++++---- .../keychain/ui/EditKeyActivity.java | 28 ++++++++++------------ .../keychain/ui/widget/KeyEditor.java | 10 ++++---- 3 files changed, 29 insertions(+), 24 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 7ac1747b7..3bb2280c1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -26,6 +26,7 @@ import android.os.Message; import android.os.Messenger; import android.os.RemoteException; +import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.openpgp.*; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; @@ -145,7 +146,7 @@ public class KeychainIntentService extends IntentService */ // keys public static final String RESULT_NEW_KEY = "new_key"; - public static final String RESULT_NEW_KEY2 = "new_key2"; + public static final String RESULT_KEY_USAGES = "new_key_usages"; // encrypt public static final String RESULT_SIGNATURE_BYTES = "signature_data"; @@ -563,6 +564,8 @@ public class KeychainIntentService extends IntentService try { /* Input */ String passphrase = data.getString(GENERATE_KEY_SYMMETRIC_PASSPHRASE); + ArrayList newKeys = new ArrayList(); + ArrayList keyUsageList = new ArrayList(); /* Operation */ int keysTotal = 2; @@ -576,11 +579,15 @@ public class KeychainIntentService extends IntentService PGPSecretKey masterKey = keyOperations.createKey(Id.choice.algorithm.rsa, 4096, passphrase, true); + newKeys.add(masterKey); + keyUsageList.add(KeyFlags.CERTIFY_OTHER); keysCreated++; setProgress(keysCreated, keysTotal); PGPSecretKey subKey = keyOperations.createKey(Id.choice.algorithm.rsa, 4096, passphrase, false); + newKeys.add(subKey); + keyUsageList.add(KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE); keysCreated++; setProgress(keysCreated, keysTotal); @@ -588,11 +595,11 @@ public class KeychainIntentService extends IntentService // for sign /* Output */ + Bundle resultData = new Bundle(); resultData.putByteArray(RESULT_NEW_KEY, - PgpConversionHelper.PGPSecretKeyToBytes(masterKey)); - resultData.putByteArray(RESULT_NEW_KEY2, - PgpConversionHelper.PGPSecretKeyToBytes(subKey)); + PgpConversionHelper.PGPSecretKeyArrayListToBytes(newKeys)); + resultData.putIntegerArrayList(RESULT_KEY_USAGES, keyUsageList); OtherHelper.logDebugBundle(resultData, "resultData"); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index b7fffc7ff..db0fae9b3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -235,22 +235,20 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { // get new key from data bundle returned from service Bundle data = message.getData(); - PGPSecretKey masterKey = PgpConversionHelper - .BytesToPGPSecretKey(data + + ArrayList newKeys = + PgpConversionHelper.BytesToPGPSecretKeyList(data .getByteArray(KeychainIntentService.RESULT_NEW_KEY)); - PGPSecretKey subKey = PgpConversionHelper - .BytesToPGPSecretKey(data - .getByteArray(KeychainIntentService.RESULT_NEW_KEY2)); - - //We must set the key flags here as they are not set when we make the - //key pair. Because we are not generating hashed packets there... - // add master key - mKeys.add(masterKey); - mKeysUsages.add(KeyFlags.CERTIFY_OTHER); - - // add sub key - mKeys.add(subKey); - mKeysUsages.add(KeyFlags.ENCRYPT_COMMS + KeyFlags.ENCRYPT_STORAGE); + + ArrayList keyUsageFlags = data.getIntegerArrayList( + KeychainIntentService.RESULT_KEY_USAGES); + + if (newKeys.size() == keyUsageFlags.size()) { + for (int i = 0; i < newKeys.size(); ++i) { + mKeys.add(newKeys.get(i)); + mKeysUsages.add(keyUsageFlags.get(i)); + } + } buildLayout(true); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 0dfc6dc5e..038f8507e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -252,11 +252,11 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mIsNewKey = isNewKey; if (isNewKey) { mUsage = usage; - mChkCertify.setChecked((usage &= KeyFlags.CERTIFY_OTHER) == KeyFlags.CERTIFY_OTHER); - mChkSign.setChecked((usage &= KeyFlags.SIGN_DATA) == KeyFlags.SIGN_DATA); - mChkEncrypt.setChecked(((usage &= KeyFlags.ENCRYPT_COMMS) == KeyFlags.ENCRYPT_COMMS) || - ((usage &= KeyFlags.ENCRYPT_STORAGE) == KeyFlags.ENCRYPT_STORAGE)); - mChkAuthenticate.setChecked((usage &= KeyFlags.AUTHENTICATION) == KeyFlags.AUTHENTICATION); + mChkCertify.setChecked((usage & KeyFlags.CERTIFY_OTHER) == KeyFlags.CERTIFY_OTHER); + mChkSign.setChecked((usage & KeyFlags.SIGN_DATA) == KeyFlags.SIGN_DATA); + mChkEncrypt.setChecked(((usage & KeyFlags.ENCRYPT_COMMS) == KeyFlags.ENCRYPT_COMMS) || + ((usage & KeyFlags.ENCRYPT_STORAGE) == KeyFlags.ENCRYPT_STORAGE)); + mChkAuthenticate.setChecked((usage & KeyFlags.AUTHENTICATION) == KeyFlags.AUTHENTICATION); } else { mUsage = PgpKeyHelper.getKeyUsage(key); mOriginalUsage = mUsage; -- cgit v1.2.3 From 5bc902dbb1834cc07e9f6712d7a43450028ef459 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Mon, 31 Mar 2014 23:23:51 +0100 Subject: create three keys by default --- .../keychain/service/KeychainIntentService.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 3bb2280c1..f616f7300 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -568,7 +568,7 @@ public class KeychainIntentService extends IntentService ArrayList keyUsageList = new ArrayList(); /* Operation */ - int keysTotal = 2; + int keysTotal = 3; int keysCreated = 0; setProgress( getApplicationContext().getResources(). @@ -591,6 +591,13 @@ public class KeychainIntentService extends IntentService keysCreated++; setProgress(keysCreated, keysTotal); + subKey = keyOperations.createKey(Id.choice.algorithm.rsa, + 4096, passphrase, false); + newKeys.add(subKey); + keyUsageList.add(KeyFlags.SIGN_DATA); + keysCreated++; + setProgress(keysCreated, keysTotal); + // TODO: default to one master for cert, one sub for encrypt and one sub // for sign -- cgit v1.2.3 From 9283205ea8a0dfb57320ec0387bc9c9f89f03dc2 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Tue, 1 Apr 2014 00:37:18 +0100 Subject: don't disable save button, show message if nothing needs to be done --- .../java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index db0fae9b3..9df84065f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -42,6 +42,8 @@ import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.LinearLayout; import android.widget.Toast; import com.beardedhen.androidbootstrap.BootstrapButton; +import com.devspark.appmsg.AppMsg; + import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; import org.sufficientlysecure.keychain.Constants; @@ -105,7 +107,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener private boolean mIsPassPhraseSet; private boolean mNeedsSaving; private boolean mIsBrandNewKeyring = false; - private MenuItem mSaveButton; private BootstrapButton mChangePassphrase; @@ -323,8 +324,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.key_edit, menu); - mSaveButton = menu.findItem(R.id.menu_key_edit_save); - mSaveButton.setEnabled(needsSaving()); //totally get rid of some actions for new keys if (mDataUri == null) { MenuItem mButton = menu.findItem(R.id.menu_key_edit_export_file); @@ -569,6 +568,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener Toast.makeText(this, getString(R.string.error_message, e.getMessage()), Toast.LENGTH_SHORT).show(); } + } else { + AppMsg.makeText(this, R.string.error_change_something_first, AppMsg.STYLE_ALERT).show(); } } -- cgit v1.2.3 From 4c3506f4b1878bd785df9f8a639275bba243d945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 13:25:44 +0200 Subject: Experimental work on a fragment-based encrypt activity --- .../keychain/ui/DecryptActivity.java | 13 - .../keychain/ui/DecryptFileFragment.java | 26 +- .../keychain/ui/DecryptFragment.java | 6 +- .../keychain/ui/DecryptMessageFragment.java | 11 +- .../keychain/ui/EncryptActivity.java | 969 ++++----------------- .../keychain/ui/EncryptActivityInterface.java | 14 + .../keychain/ui/EncryptAsymmetricFragment.java | 283 ++++++ .../keychain/ui/EncryptFileFragment.java | 415 +++++++++ .../keychain/ui/EncryptMessageFragment.java | 289 ++++++ .../keychain/ui/EncryptSymmetricFragment.java | 96 ++ 10 files changed, 1265 insertions(+), 857 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index d6dad424e..046d80b72 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -22,23 +22,13 @@ import android.net.Uri; import android.os.Bundle; import android.support.v4.view.PagerTabStrip; import android.support.v4.view.ViewPager; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.ImageView; -import android.widget.RelativeLayout; -import android.widget.TextView; import android.widget.Toast; -import com.beardedhen.androidbootstrap.BootstrapButton; -import com.devspark.appmsg.AppMsg; - -import org.openintents.openpgp.OpenPgpSignatureResult; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.pgp.PgpHelper; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter; import org.sufficientlysecure.keychain.util.Log; @@ -47,7 +37,6 @@ import java.util.regex.Matcher; public class DecryptActivity extends DrawerActivity { /* Intents */ - // without permission public static final String ACTION_DECRYPT = Constants.INTENT_PREFIX + "DECRYPT"; /* EXTRA keys for input */ @@ -64,9 +53,7 @@ public class DecryptActivity extends DrawerActivity { private static final int PAGER_TAB_MESSAGE = 0; private static final int PAGER_TAB_FILE = 1; - private void initView() { - // Pager mViewPager = (ViewPager) findViewById(R.id.decrypt_pager); mPagerTabStrip = (PagerTabStrip) findViewById(R.id.decrypt_pager_tab_strip); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index 069a5a584..a929047b8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Dominik Schürmann + * Copyright (C) 2014 Dominik Schürmann * * 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 @@ -49,20 +49,19 @@ import java.io.File; public class DecryptFileFragment extends DecryptFragment { public static final String ARG_FILENAME = "filename"; + private static final int RESULT_CODE_FILE = 0x00007003; + + // view private EditText mFilename; private CheckBox mDeleteAfter; private BootstrapButton mBrowse; private BootstrapButton mDecryptButton; - private String mInputFilename = null; private String mOutputFilename = null; private FileDialogFragment mFileDialog; - private static final int RESULT_CODE_FILE = 0x00007003; - - /** * Inflate the layout for this fragment */ @@ -72,14 +71,14 @@ public class DecryptFileFragment extends DecryptFragment { mFilename = (EditText) view.findViewById(R.id.decrypt_file_filename); mBrowse = (BootstrapButton) view.findViewById(R.id.decrypt_file_browse); + mDeleteAfter = (CheckBox) view.findViewById(R.id.decrypt_file_delete_after_decryption); + mDecryptButton = (BootstrapButton) view.findViewById(R.id.decrypt_file_action_decrypt); mBrowse.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { FileHelper.openFile(DecryptFileFragment.this, mFilename.getText().toString(), "*/*", RESULT_CODE_FILE); } }); - mDeleteAfter = (CheckBox) view.findViewById(R.id.decrypt_file_delete_after_decryption); - mDecryptButton = (BootstrapButton) view.findViewById(R.id.decrypt_file_action_decrypt); mDecryptButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -87,12 +86,17 @@ public class DecryptFileFragment extends DecryptFragment { } }); + return view; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + String filename = getArguments().getString(ARG_FILENAME); if (filename != null) { mFilename.setText(filename); } - - return view; } private void guessOutputFilename() { @@ -193,14 +197,12 @@ public class DecryptFileFragment extends DecryptFragment { // get returned data bundle Bundle returnData = message.getData(); - PgpDecryptVerifyResult decryptVerifyResult = returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT); if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded()); } else { - if (mDeleteAfter.isChecked()) { // Create and show dialog to delete original file DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment @@ -208,13 +210,11 @@ public class DecryptFileFragment extends DecryptFragment { deleteFileDialog.show(getActivity().getSupportFragmentManager(), "deleteDialog"); } - OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); // display signature result in activity onSignatureResult(signatureResult); } - } } }; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index 4c0c80742..fd7aef353 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Dominik Schürmann + * Copyright (C) 2014 Dominik Schürmann * * 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 @@ -187,6 +187,10 @@ public class DecryptFragment extends Fragment { } } + /** + * Should be overridden by MessageFragment and FileFragment to start actual decryption + * @param passphrase + */ protected void decryptStart(String passphrase) { } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java index 3a8aaec42..94034b356 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Dominik Schürmann + * Copyright (C) 2014 Dominik Schürmann * * 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 @@ -50,7 +50,6 @@ public class DecryptMessageFragment extends DecryptFragment { private BootstrapButton mDecryptButton; private BootstrapButton mDecryptFromCLipboardButton; - /** * Inflate the layout for this fragment */ @@ -61,14 +60,12 @@ public class DecryptMessageFragment extends DecryptFragment { mMessage = (EditText) view.findViewById(R.id.message); mDecryptButton = (BootstrapButton) view.findViewById(R.id.action_decrypt); mDecryptFromCLipboardButton = (BootstrapButton) view.findViewById(R.id.action_decrypt_from_clipboard); - mDecryptButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { decryptStart(null); } }); - mDecryptFromCLipboardButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -93,6 +90,7 @@ public class DecryptMessageFragment extends DecryptFragment { private void decryptFromClipboard() { CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity()); + // only decrypt if clipboard content is available and a pgp message or cleartext signature if (clipboardText != null) { Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText); if (!matcher.matches()) { @@ -146,14 +144,12 @@ public class DecryptMessageFragment extends DecryptFragment { // get returned data bundle Bundle returnData = message.getData(); - PgpDecryptVerifyResult decryptVerifyResult = returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT); if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded()); } else { - AppMsg.makeText(getActivity(), R.string.decryption_successful, AppMsg.STYLE_INFO).show(); @@ -162,13 +158,11 @@ public class DecryptMessageFragment extends DecryptFragment { mMessage.setText(new String(decryptedMessage)); mMessage.setHorizontallyScrolling(false); - OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); // display signature result in activity onSignatureResult(signatureResult); } - } } }; @@ -184,5 +178,4 @@ public class DecryptMessageFragment extends DecryptFragment { getActivity().startService(intent); } - } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index cc8224f06..47c4347f6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -17,49 +17,25 @@ package org.sufficientlysecure.keychain.ui; -import android.app.ProgressDialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.Messenger; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.animation.AlphaAnimation; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.widget.*; -import com.beardedhen.androidbootstrap.BootstrapButton; -import com.beardedhen.androidbootstrap.FontAwesomeText; -import com.devspark.appmsg.AppMsg; -import org.spongycastle.openpgp.PGPPublicKey; -import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; +import android.support.v4.view.PagerTabStrip; +import android.support.v4.view.ViewPager; +import android.widget.Toast; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.helper.FileHelper; -import org.sufficientlysecure.keychain.helper.Preferences; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.KeychainIntentService; -import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; -import org.sufficientlysecure.keychain.service.PassphraseCacheService; -import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; -import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; -import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; -import org.sufficientlysecure.keychain.util.Choice; +import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter; import org.sufficientlysecure.keychain.util.Log; -import java.io.File; -import java.util.Vector; - -public class EncryptActivity extends DrawerActivity { +public class EncryptActivity extends DrawerActivity implements + EncryptSymmetricFragment.OnSymmetricKeySelection, + EncryptAsymmetricFragment.OnAsymmetricKeySelection, + EncryptActivityInterface { /* Intents */ public static final String ACTION_ENCRYPT = Constants.INTENT_PREFIX + "ENCRYPT"; @@ -74,52 +50,100 @@ public class EncryptActivity extends DrawerActivity { public static final String EXTRA_SIGNATURE_KEY_ID = "signature_key_id"; public static final String EXTRA_ENCRYPTION_KEY_IDS = "encryption_key_ids"; + // view + ViewPager mViewPagerMode; + PagerTabStrip mPagerTabStripMode; + PagerTabStripAdapter mTabsAdapterMode; + ViewPager mViewPagerContent; + PagerTabStrip mPagerTabStripContent; + PagerTabStripAdapter mTabsAdapterContent; + + // tabs + Bundle mAsymmetricFragmentBundle = new Bundle(); + Bundle mSymmetricFragmentBundle = new Bundle(); + Bundle mMessageFragmentBundle = new Bundle(); + Bundle mFileFragmentBundle = new Bundle(); + int mSwitchToMode = PAGER_MODE_ASYMMETRIC; + int mSwitchToContent = PAGER_CONTENT_MESSAGE; + + private static final int PAGER_MODE_ASYMMETRIC = 0; + private static final int PAGER_MODE_SYMMETRIC = 1; + private static final int PAGER_CONTENT_MESSAGE = 0; + private static final int PAGER_CONTENT_FILE = 1; + + // model private long mEncryptionKeyIds[] = null; + private long mSigningKeyId = Id.key.none; + private String mPassphrase; + private String mPassphraseAgain; - private EditText mMessage = null; - private BootstrapButton mSelectKeysButton = null; + private boolean mAsciiArmorDemand = false; + private boolean mOverrideAsciiArmor = false; - private CheckBox mSign = null; - private TextView mMainUserId = null; - private TextView mMainUserIdRest = null; + private boolean mGenerateSignature = false; - private ViewFlipper mSource = null; - private TextView mSourceLabel = null; - private ImageView mSourcePrevious = null; - private ImageView mSourceNext = null; - private ViewFlipper mMode = null; - private TextView mModeLabel = null; - private ImageView mModePrevious = null; - private ImageView mModeNext = null; + @Override + public void onSigningKeySelected(long signingKeyId) { + mSigningKeyId = signingKeyId; + } - private int mEncryptTarget; + @Override + public void onEncryptionKeysSelected(long[] encryptionKeyIds) { + mEncryptionKeyIds = encryptionKeyIds; + } - private EditText mPassphrase = null; - private EditText mPassphraseAgain = null; - private CheckBox mAsciiArmor = null; - private Spinner mFileCompression = null; + @Override + public void onPassphraseUpdate(String passphrase) { + mPassphrase = passphrase; + } - private EditText mFilename = null; - private CheckBox mDeleteAfter = null; - private CheckBox mShareAfter = null; - private BootstrapButton mBrowse = null; + @Override + public void onPassphraseAgainUpdate(String passphrase) { + mPassphraseAgain = passphrase; + } - private String mInputFilename = null; - private String mOutputFilename = null; + @Override + public boolean isModeSymmetric() { + if (PAGER_MODE_SYMMETRIC == mViewPagerMode.getCurrentItem()) { + return true; + } else { + return false; + } + } - private boolean mAsciiArmorDemand = false; - private boolean mOverrideAsciiArmor = false; + @Override + public long getSignatureKey() { + return mSigningKeyId; + } - private boolean mGenerateSignature = false; + @Override + public long[] getEncryptionKeys() { + return mEncryptionKeyIds; + } - private long mSecretKeyId = Id.key.none; + @Override + public String getPassphrase() { + return mPassphrase; + } - private FileDialogFragment mFileDialog; + @Override + public String getPassphraseAgain() { + return mPassphraseAgain; + } - private BootstrapButton mEncryptShare; - private BootstrapButton mEncryptClipboard; - private BootstrapButton mEncryptFile; + + private void initView() { + mViewPagerMode = (ViewPager) findViewById(R.id.encrypt_pager_mode); + mPagerTabStripMode = (PagerTabStrip) findViewById(R.id.encrypt_pager_tab_strip_mode); + mViewPagerContent = (ViewPager) findViewById(R.id.encrypt_pager_content); + mPagerTabStripContent = (PagerTabStrip) findViewById(R.id.encrypt_pager_tab_strip_content); + + mTabsAdapterMode = new PagerTabStripAdapter(this); + mViewPagerMode.setAdapter(mTabsAdapterMode); + mTabsAdapterContent = new PagerTabStripAdapter(this); + mViewPagerContent.setAdapter(mTabsAdapterContent); + } @Override public void onCreate(Bundle savedInstanceState) { @@ -137,11 +161,13 @@ public class EncryptActivity extends DrawerActivity { // Handle intent actions handleActions(getIntent()); - updateView(); - updateSource(); - updateMode(); + mTabsAdapterMode.addTab(EncryptAsymmetricFragment.class, mAsymmetricFragmentBundle, getString(R.string.label_asymmetric)); + mTabsAdapterMode.addTab(EncryptSymmetricFragment.class, mSymmetricFragmentBundle, getString(R.string.label_symmetric)); + mViewPagerMode.setCurrentItem(mSwitchToMode); - updateActionBarButtons(); + mTabsAdapterContent.addTab(EncryptMessageFragment.class, mMessageFragmentBundle, getString(R.string.label_message)); + mTabsAdapterContent.addTab(EncryptFileFragment.class, mFileFragmentBundle, getString(R.string.label_file)); + mViewPagerContent.setCurrentItem(mSwitchToContent); } /** @@ -183,8 +209,7 @@ public class EncryptActivity extends DrawerActivity { if (extras.containsKey(EXTRA_ASCII_ARMOR)) { mAsciiArmorDemand = extras.getBoolean(EXTRA_ASCII_ARMOR, true); - mOverrideAsciiArmor = true; - mAsciiArmor.setChecked(mAsciiArmorDemand); + mFileFragmentBundle.putBoolean(EncryptFileFragment.ARG_ASCII_ARMOR, mAsciiArmorDemand); } String textData = extras.getString(EXTRA_TEXT); @@ -193,20 +218,17 @@ public class EncryptActivity extends DrawerActivity { long[] encryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS); // preselect keys given by intent - preselectKeys(signatureKeyId, encryptionKeyIds); + mAsymmetricFragmentBundle.putLongArray(EncryptAsymmetricFragment.ARG_ENCRYPTION_KEY_IDS, encryptionKeyIds); + mAsymmetricFragmentBundle.putLong(EncryptAsymmetricFragment.ARG_SIGNATURE_KEY_ID, signatureKeyId); + mSwitchToMode = PAGER_MODE_ASYMMETRIC; /** * Main Actions */ if (ACTION_ENCRYPT.equals(action) && textData != null) { // encrypt text based on given extra - - mMessage.setText(textData); - mSource.setInAnimation(null); - mSource.setOutAnimation(null); - while (mSource.getCurrentView().getId() != R.id.sourceMessage) { - mSource.showNext(); - } + mMessageFragmentBundle.putString(EncryptMessageFragment.ARG_TEXT, textData); + mSwitchToContent = PAGER_CONTENT_MESSAGE; } else if (ACTION_ENCRYPT.equals(action) && uri != null) { // encrypt file based on Uri @@ -214,14 +236,8 @@ public class EncryptActivity extends DrawerActivity { String path = FileHelper.getPath(this, uri); if (path != null) { - mInputFilename = path; - mFilename.setText(mInputFilename); - - mSource.setInAnimation(null); - mSource.setOutAnimation(null); - while (mSource.getCurrentView().getId() != R.id.sourceFile) { - mSource.showNext(); - } + mFileFragmentBundle.putString(EncryptFileFragment.ARG_FILENAME, path); + mSwitchToContent = PAGER_CONTENT_FILE; } else { Log.e(Constants.TAG, "Direct binary data without actual file in filesystem is not supported by Intents. Please use the Remote Service API!"); @@ -236,740 +252,51 @@ public class EncryptActivity extends DrawerActivity { } } - /** - * If an Intent gives a signatureKeyId and/or encryptionKeyIds, preselect those! - * - * @param preselectedSignatureKeyId - * @param preselectedEncryptionKeyIds - */ - private void preselectKeys(long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds) { - if (preselectedSignatureKeyId != 0) { - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, - preselectedSignatureKeyId); - PGPSecretKey masterKey = null; - if (keyRing != null) { - masterKey = PgpKeyHelper.getMasterKey(keyRing); - if (masterKey != null) { - Vector signKeys = PgpKeyHelper.getUsableSigningKeys(keyRing); - if (signKeys.size() > 0) { - mSecretKeyId = masterKey.getKeyID(); - } - } - } - } - - if (preselectedEncryptionKeyIds != null) { - Vector goodIds = new Vector(); - for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) { - PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, - preselectedEncryptionKeyIds[i]); - PGPPublicKey masterKey = null; - if (keyRing == null) { - continue; - } - masterKey = PgpKeyHelper.getMasterKey(keyRing); - if (masterKey == null) { - continue; - } - Vector encryptKeys = PgpKeyHelper.getUsableEncryptKeys(keyRing); - if (encryptKeys.size() == 0) { - continue; - } - goodIds.add(masterKey.getKeyID()); - } - if (goodIds.size() > 0) { - mEncryptionKeyIds = new long[goodIds.size()]; - for (int i = 0; i < goodIds.size(); ++i) { - mEncryptionKeyIds[i] = goodIds.get(i); - } - } - } - } - - /** - * Guess output filename based on input path - * - * @param path - * @return Suggestion for output filename - */ - private String guessOutputFilename(String path) { - // output in the same directory but with additional ending - File file = new File(path); - String ending = (mAsciiArmor.isChecked() ? ".asc" : ".gpg"); - String outputFilename = file.getParent() + File.separator + file.getName() + ending; - - return outputFilename; - } - - private void updateSource() { - switch (mSource.getCurrentView().getId()) { - case R.id.sourceFile: { - mSourceLabel.setText(R.string.label_file); - break; - } - - case R.id.sourceMessage: { - mSourceLabel.setText(R.string.label_message); - break; - } - - default: { - break; - } - } - updateActionBarButtons(); - } - - /** - * Update ActionBar buttons based on current selection in view - */ - private void updateActionBarButtons() { - switch (mSource.getCurrentView().getId()) { - case R.id.sourceFile: { - mEncryptShare.setVisibility(View.GONE); - mEncryptClipboard.setVisibility(View.GONE); - mEncryptFile.setVisibility(View.VISIBLE); - break; - } - - case R.id.sourceMessage: { - mSourceLabel.setText(R.string.label_message); - - mEncryptShare.setVisibility(View.VISIBLE); - mEncryptClipboard.setVisibility(View.VISIBLE); - mEncryptFile.setVisibility(View.GONE); - - if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { - mEncryptShare.setEnabled(true); - mEncryptClipboard.setEnabled(true); - } else { - if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { - if (mSecretKeyId == 0) { - mEncryptShare.setEnabled(false); - mEncryptClipboard.setEnabled(false); - } else { - mEncryptShare.setEnabled(true); - mEncryptClipboard.setEnabled(true); - } - } else { - mEncryptShare.setEnabled(true); - mEncryptClipboard.setEnabled(true); - } - } - break; - } - - default: { - break; - } - } - - } - - private void updateMode() { - switch (mMode.getCurrentView().getId()) { - case R.id.modeAsymmetric: { - mModeLabel.setText(R.string.label_asymmetric); - break; - } - - case R.id.modeSymmetric: { - mModeLabel.setText(R.string.label_symmetric); - break; - } - - default: { - break; - } - } - updateActionBarButtons(); - } - - private void encryptToClipboardClicked() { - mEncryptTarget = Id.target.clipboard; - initiateEncryption(); - } - - private void encryptClicked() { - Log.d(Constants.TAG, "encryptClicked invoked!"); - - if (mSource.getCurrentView().getId() == R.id.sourceFile) { - mEncryptTarget = Id.target.file; - } else { - mEncryptTarget = Id.target.email; - } - initiateEncryption(); - } - - private void initiateEncryption() { - if (mEncryptTarget == Id.target.file) { - String currentFilename = mFilename.getText().toString(); - if (mInputFilename == null || !mInputFilename.equals(currentFilename)) { - mInputFilename = mFilename.getText().toString(); - } - - mOutputFilename = guessOutputFilename(mInputFilename); - - if (mInputFilename.equals("")) { - AppMsg.makeText(this, R.string.no_file_selected, AppMsg.STYLE_ALERT).show(); - return; - } - - if (!mInputFilename.startsWith("content")) { - File file = new File(mInputFilename); - if (!file.exists() || !file.isFile()) { - AppMsg.makeText( - this, - getString(R.string.error_message, - getString(R.string.error_file_not_found)), AppMsg.STYLE_ALERT) - .show(); - return; - } - } - } - - // symmetric encryption - if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { - boolean gotPassPhrase = false; - String passphrase = mPassphrase.getText().toString(); - String passphraseAgain = mPassphraseAgain.getText().toString(); - if (!passphrase.equals(passphraseAgain)) { - AppMsg.makeText(this, R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show(); - return; - } - - gotPassPhrase = (passphrase.length() != 0); - if (!gotPassPhrase) { - AppMsg.makeText(this, R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT) - .show(); - return; - } - } else { - boolean encryptIt = (mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0); - // for now require at least one form of encryption for files - if (!encryptIt && mEncryptTarget == Id.target.file) { - AppMsg.makeText(this, R.string.select_encryption_key, AppMsg.STYLE_ALERT).show(); - return; - } - - if (!encryptIt && mSecretKeyId == 0) { - AppMsg.makeText(this, R.string.select_encryption_or_signature_key, - AppMsg.STYLE_ALERT).show(); - return; - } - - if (mSecretKeyId != 0 - && PassphraseCacheService.getCachedPassphrase(this, mSecretKeyId) == null) { - showPassphraseDialog(); - - return; - } - } - - if (mEncryptTarget == Id.target.file) { - showOutputFileDialog(); - } else { - encryptStart(); - } - } - - /** - * Shows passphrase dialog to cache a new passphrase the user enters for using it later for - * encryption - */ - private void showPassphraseDialog() { - // Message is received after passphrase is cached - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - if (mEncryptTarget == Id.target.file) { - showOutputFileDialog(); - } else { - encryptStart(); - } - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - try { - PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance( - EncryptActivity.this, messenger, mSecretKeyId); - - passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); - } catch (PgpGeneralException e) { - Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); - // send message to handler to start encryption directly - returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); - } - } - - private void showOutputFileDialog() { - // Message is received after file is selected - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == FileDialogFragment.MESSAGE_OKAY) { - Bundle data = message.getData(); - mOutputFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); - encryptStart(); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - mFileDialog = FileDialogFragment.newInstance(messenger, - getString(R.string.title_encrypt_to_file), - getString(R.string.specify_file_to_encrypt_to), mOutputFilename, null); - - mFileDialog.show(getSupportFragmentManager(), "fileDialog"); - } - - private void encryptStart() { - // Send all information needed to service to edit key in other thread - Intent intent = new Intent(this, KeychainIntentService.class); - - // fill values for this action - Bundle data = new Bundle(); - - boolean useAsciiArmor = true; - long encryptionKeyIds[] = null; - int compressionId = 0; - boolean signOnly = false; - long mSecretKeyIdToPass = 0; - - if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { - Log.d(Constants.TAG, "Symmetric encryption enabled!"); - String passphrase = mPassphrase.getText().toString(); - if (passphrase.length() == 0) { - passphrase = null; - } - data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase); - } else { - mSecretKeyIdToPass = mSecretKeyId; - encryptionKeyIds = mEncryptionKeyIds; - signOnly = (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0); - } - - intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN); - // choose default settings, target and data bundle by target - if (mEncryptTarget == Id.target.file) { - useAsciiArmor = mAsciiArmor.isChecked(); - compressionId = ((Choice) mFileCompression.getSelectedItem()).getId(); - - data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI); - - Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" - + mOutputFilename); - - data.putString(KeychainIntentService.ENCRYPT_INPUT_FILE, mInputFilename); - data.putString(KeychainIntentService.ENCRYPT_OUTPUT_FILE, mOutputFilename); - - } else { - useAsciiArmor = true; - compressionId = Preferences.getPreferences(this).getDefaultMessageCompression(); - - data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); - - String message = mMessage.getText().toString(); - if (signOnly) { - message = fixBadCharactersForGmail(message); - } - data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, message.getBytes()); - } - - if (mOverrideAsciiArmor) { - useAsciiArmor = mAsciiArmorDemand; - } - - data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyIdToPass); - data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, useAsciiArmor); - data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, encryptionKeyIds); - data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId); - data.putBoolean(KeychainIntentService.ENCRYPT_GENERATE_SIGNATURE, mGenerateSignature); - data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly); - - intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - - // Message is received after encrypting is done in KeychainIntentService - KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, - getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) { - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { - // get returned data bundle - Bundle data = message.getData(); - - String output; - switch (mEncryptTarget) { - case Id.target.clipboard: - output = data.getString(KeychainIntentService.RESULT_ENCRYPTED_STRING); - Log.d(Constants.TAG, "output: " + output); - ClipboardReflection.copyToClipboard(EncryptActivity.this, output); - AppMsg.makeText(EncryptActivity.this, - R.string.encryption_to_clipboard_successful, AppMsg.STYLE_INFO) - .show(); - break; - - case Id.target.email: - - output = data.getString(KeychainIntentService.RESULT_ENCRYPTED_STRING); - Log.d(Constants.TAG, "output: " + output); - - Intent sendIntent = new Intent(Intent.ACTION_SEND); - - // Type is set to text/plain so that encrypted messages can - // be sent with Whatsapp, Hangouts, SMS etc... - sendIntent.setType("text/plain"); - - sendIntent.putExtra(Intent.EXTRA_TEXT, output); - startActivity(Intent.createChooser(sendIntent, - getString(R.string.title_send_email))); - break; - - case Id.target.file: - AppMsg.makeText(EncryptActivity.this, R.string.encryption_successful, - AppMsg.STYLE_INFO).show(); - - if (mDeleteAfter.isChecked()) { - // Create and show dialog to delete original file - DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment - .newInstance(mInputFilename); - deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); - } - - if (mShareAfter.isChecked()) { - // Share encrypted file - Intent sendFileIntent = new Intent(Intent.ACTION_SEND); - sendFileIntent.setType("*/*"); - sendFileIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(mOutputFilename)); - startActivity(Intent.createChooser(sendFileIntent, - getString(R.string.title_send_file))); - } - break; - - default: - // shouldn't happen - break; - - } - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - - // show progress dialog - saveHandler.showProgressDialog(this); - - // start service with intent - startService(intent); - } - - /** - * Fixes bad message characters for gmail - * - * @param message - * @return - */ - private String fixBadCharactersForGmail(String message) { - // fix the message a bit, trailing spaces and newlines break stuff, - // because GMail sends as HTML and such things fuck up the - // signature, - // TODO: things like "<" and ">" also fuck up the signature - message = message.replaceAll(" +\n", "\n"); - message = message.replaceAll("\n\n+", "\n\n"); - message = message.replaceFirst("^\n+", ""); - // make sure there'll be exactly one newline at the end - message = message.replaceFirst("\n*$", "\n"); - - return message; - } - - private void initView() { - mSource = (ViewFlipper) findViewById(R.id.source); - mSourceLabel = (TextView) findViewById(R.id.sourceLabel); - mSourcePrevious = (ImageView) findViewById(R.id.sourcePrevious); - mSourceNext = (ImageView) findViewById(R.id.sourceNext); - - mSourcePrevious.setClickable(true); - mSourcePrevious.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_right_in)); - mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_right_out)); - mSource.showPrevious(); - updateSource(); - } - }); - - mSourceNext.setClickable(true); - OnClickListener nextSourceClickListener = new OnClickListener() { - public void onClick(View v) { - mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_left_in)); - mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_left_out)); - mSource.showNext(); - updateSource(); - } - }; - mSourceNext.setOnClickListener(nextSourceClickListener); - - mSourceLabel.setClickable(true); - mSourceLabel.setOnClickListener(nextSourceClickListener); - - mMode = (ViewFlipper) findViewById(R.id.mode); - mModeLabel = (TextView) findViewById(R.id.modeLabel); - mModePrevious = (ImageView) findViewById(R.id.modePrevious); - mModeNext = (ImageView) findViewById(R.id.modeNext); - - mModePrevious.setClickable(true); - mModePrevious.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_right_in)); - mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_right_out)); - mMode.showPrevious(); - updateMode(); - } - }); - - OnClickListener nextModeClickListener = new OnClickListener() { - public void onClick(View v) { - mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_left_in)); - mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_left_out)); - mMode.showNext(); - updateMode(); - } - }; - mModeNext.setOnClickListener(nextModeClickListener); - - mModeLabel.setClickable(true); - mModeLabel.setOnClickListener(nextModeClickListener); - - mMessage = (EditText) findViewById(R.id.message); - mSelectKeysButton = (BootstrapButton) findViewById(R.id.btn_selectEncryptKeys); - mSign = (CheckBox) findViewById(R.id.sign); - mMainUserId = (TextView) findViewById(R.id.mainUserId); - mMainUserIdRest = (TextView) findViewById(R.id.mainUserIdRest); - - mPassphrase = (EditText) findViewById(R.id.passphrase); - mPassphraseAgain = (EditText) findViewById(R.id.passphraseAgain); - - // measure the height of the source_file view and set the message view's min height to that, - // so it fills mSource fully... bit of a hack. - View tmp = findViewById(R.id.sourceFile); - tmp.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - int height = tmp.getMeasuredHeight(); - mMessage.setMinimumHeight(height); - - mFilename = (EditText) findViewById(R.id.filename); - mBrowse = (BootstrapButton) findViewById(R.id.btn_browse); - mBrowse.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - FileHelper.openFile(EncryptActivity.this, mFilename.getText().toString(), "*/*", - Id.request.filename); - } - }); - - - - - - - mFileCompression = (Spinner) findViewById(R.id.fileCompression); - Choice[] choices = new Choice[]{ - new Choice(Id.choice.compression.none, getString(R.string.choice_none) + " (" - + getString(R.string.compression_fast) + ")"), - new Choice(Id.choice.compression.zip, "ZIP (" - + getString(R.string.compression_fast) + ")"), - new Choice(Id.choice.compression.zlib, "ZLIB (" - + getString(R.string.compression_fast) + ")"), - new Choice(Id.choice.compression.bzip2, "BZIP2 (" - + getString(R.string.compression_very_slow) + ")"), }; - ArrayAdapter adapter = new ArrayAdapter(this, - android.R.layout.simple_spinner_item, choices); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - mFileCompression.setAdapter(adapter); - - int defaultFileCompression = Preferences.getPreferences(this).getDefaultFileCompression(); - for (int i = 0; i < choices.length; ++i) { - if (choices[i].getId() == defaultFileCompression) { - mFileCompression.setSelection(i); - break; - } - } - - mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterEncryption); - mShareAfter = (CheckBox) findViewById(R.id.shareAfterEncryption); - - mAsciiArmor = (CheckBox) findViewById(R.id.asciiArmour); - mAsciiArmor.setChecked(Preferences.getPreferences(this).getDefaultAsciiArmour()); - - mSelectKeysButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - selectPublicKeys(); - } - }); - - mSign.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - CheckBox checkBox = (CheckBox) v; - if (checkBox.isChecked()) { - selectSecretKey(); - } else { - mSecretKeyId = Id.key.none; - updateView(); - } - } - }); - - mEncryptClipboard = (BootstrapButton) findViewById(R.id.action_encrypt_clipboard); - mEncryptClipboard.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - encryptToClipboardClicked(); - } - }); - mEncryptShare = (BootstrapButton) findViewById(R.id.action_encrypt_share); - mEncryptShare.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - encryptClicked(); - } - }); - mEncryptFile = (BootstrapButton) findViewById(R.id.action_encrypt_file); - mEncryptFile.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - encryptClicked(); - } - }); - } - - private void updateView() { - if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { - mSelectKeysButton.setText(getString(R.string.select_keys_button_default)); - } else { - mSelectKeysButton.setText(getResources().getQuantityString( - R.plurals.select_keys_button, mEncryptionKeyIds.length, - mEncryptionKeyIds.length)); - } - - if (mSecretKeyId == Id.key.none) { - mSign.setChecked(false); - mMainUserId.setText(""); - mMainUserIdRest.setText(""); - } else { - String uid = getResources().getString(R.string.user_id_no_name); - String uidExtra = ""; - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, - mSecretKeyId); - if (keyRing != null) { - PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing); - if (key != null) { - String userId = PgpKeyHelper.getMainUserIdSafe(this, key); - String chunks[] = userId.split(" <", 2); - uid = chunks[0]; - if (chunks.length > 1) { - uidExtra = "<" + chunks[1]; - } - } - } - mMainUserId.setText(uid); - mMainUserIdRest.setText(uidExtra); - mSign.setChecked(true); - } - - updateActionBarButtons(); - } - - private void selectPublicKeys() { - Intent intent = new Intent(this, SelectPublicKeyActivity.class); - Vector keyIds = new Vector(); - if (mSecretKeyId != 0) { - keyIds.add(mSecretKeyId); - } - if (mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) { - for (int i = 0; i < mEncryptionKeyIds.length; ++i) { - keyIds.add(mEncryptionKeyIds[i]); - } - } - long[] initialKeyIds = null; - if (keyIds.size() > 0) { - initialKeyIds = new long[keyIds.size()]; - for (int i = 0; i < keyIds.size(); ++i) { - initialKeyIds[i] = keyIds.get(i); - } - } - intent.putExtra(SelectPublicKeyActivity.EXTRA_SELECTED_MASTER_KEY_IDS, initialKeyIds); - startActivityForResult(intent, Id.request.public_keys); - } - - private void selectSecretKey() { - Intent intent = new Intent(this, SelectSecretKeyActivity.class); - startActivityForResult(intent, Id.request.secret_keys); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case Id.request.filename: { - if (resultCode == RESULT_OK && data != null) { - try { - String path = FileHelper.getPath(this, data.getData()); - Log.d(Constants.TAG, "path=" + path); - - mFilename.setText(path); - } catch (NullPointerException e) { - Log.e(Constants.TAG, "Nullpointer while retrieving path!"); - } - } - return; - } - - case Id.request.public_keys: { - if (resultCode == RESULT_OK) { - Bundle bundle = data.getExtras(); - mEncryptionKeyIds = bundle - .getLongArray(SelectPublicKeyActivity.RESULT_EXTRA_MASTER_KEY_IDS); - } - updateView(); - break; - } - - case Id.request.secret_keys: { - if (resultCode == RESULT_OK) { - Uri uri_master_key = data.getData(); - mSecretKeyId = Long.valueOf(uri_master_key.getLastPathSegment()); - } else { - mSecretKeyId = Id.key.none; - } - updateView(); - break; - } - - default: { - break; - } - } - - super.onActivityResult(requestCode, resultCode, data); - } +// /** +// * Update ActionBar buttons based on current selection in view +// */ +// private void updateActionBarButtons() { +// switch (mSource.getCurrentView().getId()) { +// case R.id.sourceFile: { +// mEncryptShare.setVisibility(View.GONE); +// mEncryptClipboard.setVisibility(View.GONE); +// mEncryptFile.setVisibility(View.VISIBLE); +// break; +// } +// +// case R.id.sourceMessage: { +// mSourceLabel.setText(R.string.label_message); +// +// mEncryptShare.setVisibility(View.VISIBLE); +// mEncryptClipboard.setVisibility(View.VISIBLE); +// mEncryptFile.setVisibility(View.GONE); +// +// if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { +// mEncryptShare.setEnabled(true); +// mEncryptClipboard.setEnabled(true); +// } else { +// if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { +// if (mSecretKeyId == 0) { +// mEncryptShare.setEnabled(false); +// mEncryptClipboard.setEnabled(false); +// } else { +// mEncryptShare.setEnabled(true); +// mEncryptClipboard.setEnabled(true); +// } +// } else { +// mEncryptShare.setEnabled(true); +// mEncryptClipboard.setEnabled(true); +// } +// } +// break; +// } +// +// default: { +// break; +// } +// } +// +// } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java new file mode 100644 index 000000000..8fbabe9c0 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java @@ -0,0 +1,14 @@ +package org.sufficientlysecure.keychain.ui; + + +public interface EncryptActivityInterface { + + public boolean isModeSymmetric(); + + public long getSignatureKey(); + public long[] getEncryptionKeys(); + + public String getPassphrase(); + public String getPassphraseAgain(); + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java new file mode 100644 index 000000000..b88dafd4a --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.TextView; + +import com.beardedhen.androidbootstrap.BootstrapButton; + +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.sufficientlysecure.keychain.Id; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.provider.ProviderHelper; + +import java.util.Vector; + +public class EncryptAsymmetricFragment extends Fragment { + public static final String ARG_SIGNATURE_KEY_ID = "signature_key_id"; + public static final String ARG_ENCRYPTION_KEY_IDS = "encryption_key_ids"; + + public static final int RESULT_CODE_PUBLIC_KEYS = 0x00007001; + public static final int RESULT_CODE_SECRET_KEYS = 0x00007002; + + OnAsymmetricKeySelection mKeySelectionListener; + + // view + private BootstrapButton mSelectKeysButton; + private CheckBox mSign; + private TextView mMainUserId; + private TextView mMainUserIdRest; + + // model + private long mSecretKeyId = Id.key.none; + private long mEncryptionKeyIds[] = null; + + // Container Activity must implement this interface + public interface OnAsymmetricKeySelection { + public void onSigningKeySelected(long signingKeyId); + + public void onEncryptionKeysSelected(long[] encryptionKeyIds); + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + mKeySelectionListener = (OnAsymmetricKeySelection) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + " must implement OnAsymmetricKeySelection"); + } + } + + private void setSignatureKeyId(long signatureKeyId) { + mSecretKeyId = signatureKeyId; + mKeySelectionListener.onSigningKeySelected(signatureKeyId); + } + + private void setEncryptionKeyIds(long[] encryptionKeyIds) { + mEncryptionKeyIds = encryptionKeyIds; + mKeySelectionListener.onEncryptionKeysSelected(encryptionKeyIds); + } + + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.encrypt_asymmetric_fragment, container, false); + + mSelectKeysButton = (BootstrapButton) view.findViewById(R.id.btn_selectEncryptKeys); + mSign = (CheckBox) view.findViewById(R.id.sign); + mMainUserId = (TextView) view.findViewById(R.id.mainUserId); + mMainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); + mSelectKeysButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + selectPublicKeys(); + } + }); + mSign.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + CheckBox checkBox = (CheckBox) v; + if (checkBox.isChecked()) { + selectSecretKey(); + } else { + setSignatureKeyId(Id.key.none); + updateView(); + } + } + }); + + return view; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + long signatureKeyId = getArguments().getLong(ARG_SIGNATURE_KEY_ID); + long[] encryptionKeyIds = getArguments().getLongArray(ARG_ENCRYPTION_KEY_IDS); + + // preselect keys given by arguments (given by Intent to EncryptActivity) + preselectKeys(signatureKeyId, encryptionKeyIds); + } + + /** + * If an Intent gives a signatureKeyId and/or encryptionKeyIds, preselect those! + * + * @param preselectedSignatureKeyId + * @param preselectedEncryptionKeyIds + */ + private void preselectKeys(long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds) { + if (preselectedSignatureKeyId != 0) { + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(getActivity(), + preselectedSignatureKeyId); + PGPSecretKey masterKey; + if (keyRing != null) { + masterKey = PgpKeyHelper.getMasterKey(keyRing); + if (masterKey != null) { + Vector signKeys = PgpKeyHelper.getUsableSigningKeys(keyRing); + if (signKeys.size() > 0) { + setSignatureKeyId(masterKey.getKeyID()); + } + } + } + } + + if (preselectedEncryptionKeyIds != null) { + Vector goodIds = new Vector(); + for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) { + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(getActivity(), + preselectedEncryptionKeyIds[i]); + PGPPublicKey masterKey; + if (keyRing == null) { + continue; + } + masterKey = PgpKeyHelper.getMasterKey(keyRing); + if (masterKey == null) { + continue; + } + Vector encryptKeys = PgpKeyHelper.getUsableEncryptKeys(keyRing); + if (encryptKeys.size() == 0) { + continue; + } + goodIds.add(masterKey.getKeyID()); + } + if (goodIds.size() > 0) { + long[] keyIds = new long[goodIds.size()]; + for (int i = 0; i < goodIds.size(); ++i) { + keyIds[i] = goodIds.get(i); + } + setEncryptionKeyIds(keyIds); + } + } + } + + private void updateView() { + if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { + mSelectKeysButton.setText(getString(R.string.select_keys_button_default)); + } else { + mSelectKeysButton.setText(getResources().getQuantityString( + R.plurals.select_keys_button, mEncryptionKeyIds.length, + mEncryptionKeyIds.length)); + } + + if (mSecretKeyId == Id.key.none) { + mSign.setChecked(false); + mMainUserId.setText(""); + mMainUserIdRest.setText(""); + } else { + String uid = getResources().getString(R.string.user_id_no_name); + String uidExtra = ""; + // TODO: make it nice and use helper! + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(getActivity(), + mSecretKeyId); + if (keyRing != null) { + PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing); + if (key != null) { + String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key); + String chunks[] = userId.split(" <", 2); + uid = chunks[0]; + if (chunks.length > 1) { + uidExtra = "<" + chunks[1]; + } + } + } + mMainUserId.setText(uid); + mMainUserIdRest.setText(uidExtra); + mSign.setChecked(true); + } + +//TODO +// updateActionBarButtons(); + } + + private void selectPublicKeys() { + Intent intent = new Intent(getActivity(), SelectPublicKeyActivity.class); + Vector keyIds = new Vector(); + if (mSecretKeyId != 0) { + keyIds.add(mSecretKeyId); + } + if (mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) { + for (int i = 0; i < mEncryptionKeyIds.length; ++i) { + keyIds.add(mEncryptionKeyIds[i]); + } + } + long[] initialKeyIds = null; + if (keyIds.size() > 0) { + initialKeyIds = new long[keyIds.size()]; + for (int i = 0; i < keyIds.size(); ++i) { + initialKeyIds[i] = keyIds.get(i); + } + } + intent.putExtra(SelectPublicKeyActivity.EXTRA_SELECTED_MASTER_KEY_IDS, initialKeyIds); + startActivityForResult(intent, Id.request.public_keys); + } + + private void selectSecretKey() { + Intent intent = new Intent(getActivity(), SelectSecretKeyActivity.class); + startActivityForResult(intent, Id.request.secret_keys); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + + case RESULT_CODE_PUBLIC_KEYS: { + if (resultCode == Activity.RESULT_OK) { + Bundle bundle = data.getExtras(); + setEncryptionKeyIds(bundle + .getLongArray(SelectPublicKeyActivity.RESULT_EXTRA_MASTER_KEY_IDS)); + } + updateView(); + break; + } + + case RESULT_CODE_SECRET_KEYS: { + if (resultCode == Activity.RESULT_OK) { + Uri uri_master_key = data.getData(); + setSignatureKeyId(Long.valueOf(uri_master_key.getLastPathSegment())); + } else { + setSignatureKeyId(Id.key.none); + } + updateView(); + break; + } + + default: { + break; + } + } + + super.onActivityResult(requestCode, resultCode, data); + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java new file mode 100644 index 000000000..734941ca7 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java @@ -0,0 +1,415 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Spinner; + +import com.beardedhen.androidbootstrap.BootstrapButton; +import com.devspark.appmsg.AppMsg; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Id; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.FileHelper; +import org.sufficientlysecure.keychain.helper.Preferences; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.service.PassphraseCacheService; +import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; +import org.sufficientlysecure.keychain.util.Choice; +import org.sufficientlysecure.keychain.util.Log; + +import java.io.File; + +public class EncryptFileFragment extends Fragment { + public static final String ARG_FILENAME = "filename"; + public static final String ARG_ASCII_ARMOR = "ascii_armor"; + + private static final int RESULT_CODE_FILE = 0x00007003; + + private EncryptActivityInterface mEncryptInterface; + + // view + private CheckBox mAsciiArmor = null; + private Spinner mFileCompression = null; + private EditText mFilename = null; + private CheckBox mDeleteAfter = null; + private CheckBox mShareAfter = null; + private BootstrapButton mBrowse = null; + private BootstrapButton mEncryptFile; + + private FileDialogFragment mFileDialog; + + // model + private String mInputFilename = null; + private String mOutputFilename = null; + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + mEncryptInterface = (EncryptActivityInterface) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + " must implement EncryptActivityInterface"); + } + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.encrypt_file_fragment, container, false); + + mEncryptFile = (BootstrapButton) view.findViewById(R.id.action_encrypt_file); + mEncryptFile.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + encryptClicked(); + } + }); + + mFilename = (EditText) view.findViewById(R.id.filename); + mBrowse = (BootstrapButton) view.findViewById(R.id.btn_browse); + mBrowse.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + FileHelper.openFile(EncryptFileFragment.this, mFilename.getText().toString(), "*/*", + Id.request.filename); + } + }); + + mFileCompression = (Spinner) view.findViewById(R.id.fileCompression); + Choice[] choices = new Choice[]{ + new Choice(Id.choice.compression.none, getString(R.string.choice_none) + " (" + + getString(R.string.compression_fast) + ")"), + new Choice(Id.choice.compression.zip, "ZIP (" + + getString(R.string.compression_fast) + ")"), + new Choice(Id.choice.compression.zlib, "ZLIB (" + + getString(R.string.compression_fast) + ")"), + new Choice(Id.choice.compression.bzip2, "BZIP2 (" + + getString(R.string.compression_very_slow) + ")"),}; + ArrayAdapter adapter = new ArrayAdapter(getActivity(), + android.R.layout.simple_spinner_item, choices); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + mFileCompression.setAdapter(adapter); + + int defaultFileCompression = Preferences.getPreferences(getActivity()).getDefaultFileCompression(); + for (int i = 0; i < choices.length; ++i) { + if (choices[i].getId() == defaultFileCompression) { + mFileCompression.setSelection(i); + break; + } + } + + mDeleteAfter = (CheckBox) view.findViewById(R.id.deleteAfterEncryption); + mShareAfter = (CheckBox) view.findViewById(R.id.shareAfterEncryption); + + mAsciiArmor = (CheckBox) view.findViewById(R.id.asciiArmour); + mAsciiArmor.setChecked(Preferences.getPreferences(getActivity()).getDefaultAsciiArmour()); + + return view; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + String filename = getArguments().getString(ARG_FILENAME); + if (filename != null) { + mFilename.setText(filename); + } + boolean asciiArmor = getArguments().getBoolean(ARG_ASCII_ARMOR); + if (asciiArmor) { + mAsciiArmor.setChecked(asciiArmor); + } + } + + /** + * Guess output filename based on input path + * + * @param path + * @return Suggestion for output filename + */ + private String guessOutputFilename(String path) { + // output in the same directory but with additional ending + File file = new File(path); + String ending = (mAsciiArmor.isChecked() ? ".asc" : ".gpg"); + String outputFilename = file.getParent() + File.separator + file.getName() + ending; + + return outputFilename; + } + + private void showOutputFileDialog() { + // Message is received after file is selected + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == FileDialogFragment.MESSAGE_OKAY) { + Bundle data = message.getData(); + mOutputFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); + encryptStart(); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + mFileDialog = FileDialogFragment.newInstance(messenger, + getString(R.string.title_encrypt_to_file), + getString(R.string.specify_file_to_encrypt_to), mOutputFilename, null); + + mFileDialog.show(getActivity().getSupportFragmentManager(), "fileDialog"); + } + + private void encryptClicked() { + String currentFilename = mFilename.getText().toString(); + if (mInputFilename == null || !mInputFilename.equals(currentFilename)) { + mInputFilename = mFilename.getText().toString(); + } + + mOutputFilename = guessOutputFilename(mInputFilename); + + if (mInputFilename.equals("")) { + AppMsg.makeText(getActivity(), R.string.no_file_selected, AppMsg.STYLE_ALERT).show(); + return; + } + + if (!mInputFilename.startsWith("content")) { + File file = new File(mInputFilename); + if (!file.exists() || !file.isFile()) { + AppMsg.makeText( + getActivity(), + getString(R.string.error_message, + getString(R.string.error_file_not_found)), AppMsg.STYLE_ALERT) + .show(); + return; + } + } + + if (mEncryptInterface.isModeSymmetric()) { + // symmetric encryption + + if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) { + AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show(); + return; + } + + boolean gotPassPhrase = (mEncryptInterface.getPassphrase().length() != 0); + if (!gotPassPhrase) { + AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT) + .show(); + return; + } + } else { + // asymmetric encryption + + boolean encryptIt = (mEncryptInterface.getEncryptionKeys() != null + && mEncryptInterface.getEncryptionKeys().length > 0); + // for now require at least one form of encryption for files + if (!encryptIt) { + AppMsg.makeText(getActivity(), R.string.select_encryption_key, AppMsg.STYLE_ALERT).show(); + return; + } + + if (!encryptIt && mEncryptInterface.getSignatureKey() == 0) { + AppMsg.makeText(getActivity(), R.string.select_encryption_or_signature_key, + AppMsg.STYLE_ALERT).show(); + return; + } + + if (mEncryptInterface.getSignatureKey() != 0 + && PassphraseCacheService.getCachedPassphrase(getActivity(), mEncryptInterface.getSignatureKey()) == null) { + showPassphraseDialog(); + + return; + } + } + + showOutputFileDialog(); + } + + private void encryptStart() { + // Send all information needed to service to edit key in other thread + Intent intent = new Intent(getActivity(), KeychainIntentService.class); + + // fill values for this action + Bundle data = new Bundle(); + + boolean useAsciiArmor = true; + long encryptionKeyIds[] = null; + int compressionId = 0; + boolean signOnly = false; + long mSecretKeyIdToPass = 0; + + if (mEncryptInterface.isModeSymmetric()) { + Log.d(Constants.TAG, "Symmetric encryption enabled!"); + String passphrase = mEncryptInterface.getPassphrase(); + if (passphrase.length() == 0) { + passphrase = null; + } + data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase); + } else { + mSecretKeyIdToPass = mEncryptInterface.getSignatureKey(); + encryptionKeyIds = mEncryptInterface.getEncryptionKeys(); + signOnly = (mEncryptInterface.getEncryptionKeys() == null + || mEncryptInterface.getEncryptionKeys().length == 0); + } + + intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN); + + // choose default settings, target and data bundle by target + useAsciiArmor = mAsciiArmor.isChecked(); + compressionId = ((Choice) mFileCompression.getSelectedItem()).getId(); + + data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI); + + Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" + + mOutputFilename); + + data.putString(KeychainIntentService.ENCRYPT_INPUT_FILE, mInputFilename); + data.putString(KeychainIntentService.ENCRYPT_OUTPUT_FILE, mOutputFilename); + + + data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyIdToPass); + data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, useAsciiArmor); + data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, encryptionKeyIds); + data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId); +// data.putBoolean(KeychainIntentService.ENCRYPT_GENERATE_SIGNATURE, mGenerateSignature); + data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly); + + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Message is received after encrypting is done in KeychainIntentService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(), + getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle data = message.getData(); + + String output; + AppMsg.makeText(getActivity(), R.string.encryption_successful, + AppMsg.STYLE_INFO).show(); + + if (mDeleteAfter.isChecked()) { + // Create and show dialog to delete original file + DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment + .newInstance(mInputFilename); + deleteFileDialog.show(getActivity().getSupportFragmentManager(), "deleteDialog"); + } + + if (mShareAfter.isChecked()) { + // Share encrypted file + Intent sendFileIntent = new Intent(Intent.ACTION_SEND); + sendFileIntent.setType("*/*"); + sendFileIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(mOutputFilename)); + startActivity(Intent.createChooser(sendFileIntent, + getString(R.string.title_send_file))); + } + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(getActivity()); + + // start service with intent + getActivity().startService(intent); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case RESULT_CODE_FILE: { + if (resultCode == Activity.RESULT_OK && data != null) { + try { + String path = FileHelper.getPath(getActivity(), data.getData()); + Log.d(Constants.TAG, "path=" + path); + + mFilename.setText(path); + } catch (NullPointerException e) { + Log.e(Constants.TAG, "Nullpointer while retrieving path!"); + } + } + return; + } + + default: { + super.onActivityResult(requestCode, resultCode, data); + + break; + } + } + } + + /** + * Shows passphrase dialog to cache a new passphrase the user enters for using it later for + * encryption + */ + private void showPassphraseDialog() { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + showOutputFileDialog(); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + try { + PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance( + getActivity(), messenger, mEncryptInterface.getSignatureKey()); + + passphraseDialog.show(getActivity().getSupportFragmentManager(), "passphraseDialog"); + } catch (PgpGeneralException e) { + Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); + // send message to handler to start encryption directly + returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); + } + } +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java new file mode 100644 index 000000000..7f1d7311d --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; + +import com.beardedhen.androidbootstrap.BootstrapButton; +import com.devspark.appmsg.AppMsg; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; +import org.sufficientlysecure.keychain.helper.Preferences; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.service.PassphraseCacheService; +import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; +import org.sufficientlysecure.keychain.util.Log; + +public class EncryptMessageFragment extends Fragment { + public static final String ARG_TEXT = "text"; + + private EditText mMessage = null; + private BootstrapButton mEncryptShare; + private BootstrapButton mEncryptClipboard; + + private EncryptActivityInterface mEncryptInterface; + + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + mEncryptInterface = (EncryptActivityInterface) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + " must implement EncryptActivityInterface"); + } + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.encrypt_message_fragment, container, false); + + mMessage = (EditText) view.findViewById(R.id.message); + mEncryptClipboard = (BootstrapButton) view.findViewById(R.id.action_encrypt_clipboard); + mEncryptShare = (BootstrapButton) view.findViewById(R.id.action_encrypt_share); + mEncryptClipboard.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + encryptClicked(true); + } + }); + mEncryptShare.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + encryptClicked(false); + } + }); + + return view; + } + + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + String text = getArguments().getString(ARG_TEXT); + if (text != null) { + mMessage.setText(text); + } + } + + /** + * Fixes bad message characters for gmail + * + * @param message + * @return + */ + private String fixBadCharactersForGmail(String message) { + // fix the message a bit, trailing spaces and newlines break stuff, + // because GMail sends as HTML and such things fuck up the + // signature, + // TODO: things like "<" and ">" also fuck up the signature + message = message.replaceAll(" +\n", "\n"); + message = message.replaceAll("\n\n+", "\n\n"); + message = message.replaceFirst("^\n+", ""); + // make sure there'll be exactly one newline at the end + message = message.replaceFirst("\n*$", "\n"); + + return message; + } + + private void encryptClicked(boolean toClipboard) { + if (mEncryptInterface.isModeSymmetric()) { + // symmetric encryption + + boolean gotPassPhrase = false; + if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) { + AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show(); + return; + } + + gotPassPhrase = (mEncryptInterface.getPassphrase().length() != 0); + if (!gotPassPhrase) { + AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT) + .show(); + return; + } + } else { + // asymmetric encryption + + boolean encryptIt = (mEncryptInterface.getEncryptionKeys() != null + && mEncryptInterface.getEncryptionKeys().length > 0); + + if (!encryptIt && mEncryptInterface.getSignatureKey() == 0) { + AppMsg.makeText(getActivity(), R.string.select_encryption_or_signature_key, + AppMsg.STYLE_ALERT).show(); + return; + } + + if (mEncryptInterface.getSignatureKey() != 0 + && PassphraseCacheService.getCachedPassphrase(getActivity(), mEncryptInterface.getSignatureKey()) == null) { + showPassphraseDialog(toClipboard); + + return; + } + } + + encryptStart(toClipboard); + } + + private void encryptStart(final boolean toClipboard) { + // Send all information needed to service to edit key in other thread + Intent intent = new Intent(getActivity(), KeychainIntentService.class); + + // fill values for this action + Bundle data = new Bundle(); + + long encryptionKeyIds[] = null; + int compressionId = 0; + boolean signOnly = false; + long mSecretKeyIdToPass = 0; + + if (mEncryptInterface.isModeSymmetric()) { + Log.d(Constants.TAG, "Symmetric encryption enabled!"); + String passphrase = mEncryptInterface.getPassphrase(); + if (passphrase.length() == 0) { + passphrase = null; + } + data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase); + } else { + mSecretKeyIdToPass = mEncryptInterface.getSignatureKey(); + encryptionKeyIds = mEncryptInterface.getEncryptionKeys(); + signOnly = (mEncryptInterface.getEncryptionKeys() == null + || mEncryptInterface.getEncryptionKeys().length == 0); + } + + intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN); + + // choose default settings, target and data bundle by target + compressionId = Preferences.getPreferences(getActivity()).getDefaultMessageCompression(); + + data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); + + String message = mMessage.getText().toString(); + if (signOnly) { + message = fixBadCharactersForGmail(message); + } + data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, message.getBytes()); + + data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyIdToPass); + data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, true); + data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, encryptionKeyIds); + data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId); +// data.putBoolean(KeychainIntentService.ENCRYPT_GENERATE_SIGNATURE, mGenerateSignature); + data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly); + + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Message is received after encrypting is done in KeychainIntentService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(), + getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle data = message.getData(); + + String output; + if (toClipboard) { + output = data.getString(KeychainIntentService.RESULT_ENCRYPTED_STRING); + Log.d(Constants.TAG, "output: " + output); + ClipboardReflection.copyToClipboard(getActivity(), output); + AppMsg.makeText(getActivity(), + R.string.encryption_to_clipboard_successful, AppMsg.STYLE_INFO) + .show(); + } else { + output = data.getString(KeychainIntentService.RESULT_ENCRYPTED_STRING); + Log.d(Constants.TAG, "output: " + output); + + Intent sendIntent = new Intent(Intent.ACTION_SEND); + + // Type is set to text/plain so that encrypted messages can + // be sent with Whatsapp, Hangouts, SMS etc... + sendIntent.setType("text/plain"); + + sendIntent.putExtra(Intent.EXTRA_TEXT, output); + startActivity(Intent.createChooser(sendIntent, + getString(R.string.title_send_email))); + } + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(getActivity()); + + // start service with intent + getActivity().startService(intent); + } + + /** + * Shows passphrase dialog to cache a new passphrase the user enters for using it later for + * encryption + */ + private void showPassphraseDialog(final boolean toClipboard) { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + encryptStart(toClipboard); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + try { + PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance( + getActivity(), messenger, mEncryptInterface.getSignatureKey()); + + passphraseDialog.show(getActivity().getSupportFragmentManager(), "passphraseDialog"); + } catch (PgpGeneralException e) { + Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); + // send message to handler to start encryption directly + returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); + } + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java new file mode 100644 index 000000000..f23cc565a --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; + +import org.sufficientlysecure.keychain.R; + +public class EncryptSymmetricFragment extends Fragment { + + OnSymmetricKeySelection mPassphraseUpdateListener; + + private EditText mPassphrase; + private EditText mPassphraseAgain; + + // Container Activity must implement this interface + public interface OnSymmetricKeySelection { + public void onPassphraseUpdate(String passphrase); + + public void onPassphraseAgainUpdate(String passphrase); + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + mPassphraseUpdateListener = (OnSymmetricKeySelection) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + " must implement OnSymmetricKeySelection"); + } + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.encrypt_symmetric_fragment, container, false); + + mPassphrase = (EditText) view.findViewById(R.id.passphrase); + mPassphraseAgain = (EditText) view.findViewById(R.id.passphraseAgain); + mPassphrase.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + mPassphraseUpdateListener.onPassphraseUpdate(s.toString()); + } + }); + mPassphraseAgain.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + mPassphraseUpdateListener.onPassphraseAgainUpdate(s.toString()); + } + }); + + return view; + } +} -- cgit v1.2.3 From c859bbb6da295afe16bf02e0d8d73f36e99c546a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 14:10:32 +0200 Subject: Fix symmetric encryption and cleanup --- .../keychain/pgp/PgpSignEncrypt.java | 20 ++++---- .../keychain/service/KeychainIntentService.java | 6 +-- .../keychain/ui/EncryptActivity.java | 59 ++-------------------- .../keychain/ui/EncryptActivityInterface.java | 18 ++++++- .../keychain/ui/EncryptAsymmetricFragment.java | 11 ++-- .../keychain/ui/EncryptFileFragment.java | 54 +++++++++----------- .../keychain/ui/EncryptMessageFragment.java | 57 ++++++++++----------- .../keychain/ui/EncryptSymmetricFragment.java | 2 + 8 files changed, 91 insertions(+), 136 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java index 737e9c75d..6d80c154b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.pgp; import android.content.Context; + import org.spongycastle.bcpg.ArmoredOutputStream; import org.spongycastle.bcpg.BCPGOutputStream; import org.spongycastle.openpgp.*; @@ -50,7 +51,7 @@ public class PgpSignEncrypt { private boolean mEnableAsciiArmorOutput; private int mCompressionId; private long[] mEncryptionKeyIds; - private String mEncryptionPassphrase; + private String mSymmetricPassphrase; private int mSymmetricEncryptionAlgorithm; private long mSignatureKeyId; private int mSignatureHashAlgorithm; @@ -67,7 +68,7 @@ public class PgpSignEncrypt { this.mEnableAsciiArmorOutput = builder.mEnableAsciiArmorOutput; this.mCompressionId = builder.mCompressionId; this.mEncryptionKeyIds = builder.mEncryptionKeyIds; - this.mEncryptionPassphrase = builder.mEncryptionPassphrase; + this.mSymmetricPassphrase = builder.mSymmetricPassphrase; this.mSymmetricEncryptionAlgorithm = builder.mSymmetricEncryptionAlgorithm; this.mSignatureKeyId = builder.mSignatureKeyId; this.mSignatureHashAlgorithm = builder.mSignatureHashAlgorithm; @@ -85,8 +86,8 @@ public class PgpSignEncrypt { private ProgressDialogUpdater mProgress = null; private boolean mEnableAsciiArmorOutput = false; private int mCompressionId = Id.choice.compression.none; - private long[] mEncryptionKeyIds = new long[0]; - private String mEncryptionPassphrase = null; + private long[] mEncryptionKeyIds = null; + private String mSymmetricPassphrase = null; private int mSymmetricEncryptionAlgorithm = 0; private long mSignatureKeyId = Id.key.none; private int mSignatureHashAlgorithm = 0; @@ -119,8 +120,8 @@ public class PgpSignEncrypt { return this; } - public Builder encryptionPassphrase(String encryptionPassphrase) { - this.mEncryptionPassphrase = encryptionPassphrase; + public Builder symmetricPassphrase(String symmetricPassphrase) { + this.mSymmetricPassphrase = symmetricPassphrase; return this; } @@ -181,7 +182,8 @@ public class PgpSignEncrypt { NoSuchAlgorithmException, SignatureException { boolean enableSignature = mSignatureKeyId != Id.key.none; - boolean enableEncryption = (mEncryptionKeyIds.length != 0 || mEncryptionPassphrase != null); + boolean enableEncryption = ((mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) + || mSymmetricPassphrase != null); boolean enableCompression = (enableEncryption && mCompressionId != Id.choice.compression.none); Log.d(Constants.TAG, "enableSignature:" + enableSignature @@ -246,12 +248,12 @@ public class PgpSignEncrypt { cPk = new PGPEncryptedDataGenerator(encryptorBuilder); - if (mEncryptionKeyIds.length == 0) { + if (mSymmetricPassphrase != null) { // Symmetric encryption Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption"); JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = - new JcePBEKeyEncryptionMethodGenerator(mEncryptionPassphrase.toCharArray()); + new JcePBEKeyEncryptionMethodGenerator(mSymmetricPassphrase.toCharArray()); cPk.addMethod(symmetricEncryptionGenerator); } else { // Asymmetric encryption diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index f616f7300..46033d094 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -43,7 +43,6 @@ import org.sufficientlysecure.keychain.util.*; import java.io.*; import java.util.ArrayList; -import java.util.GregorianCalendar; import java.util.List; /** @@ -99,6 +98,7 @@ public class KeychainIntentService extends IntentService public static final String ENCRYPT_INPUT_FILE = "input_file"; public static final String ENCRYPT_OUTPUT_FILE = "output_file"; public static final String ENCRYPT_PROVIDER_URI = "provider_uri"; + public static final String ENCRYPT_SYMMETRIC_PASSPHRASE = "passphrase"; // decrypt/verify public static final String DECRYPT_CIPHERTEXT_BYTES = "ciphertext_bytes"; @@ -221,7 +221,7 @@ public class KeychainIntentService extends IntentService int target = data.getInt(TARGET); long secretKeyId = data.getLong(ENCRYPT_SECRET_KEY_ID); - String encryptionPassphrase = data.getString(GENERATE_KEY_SYMMETRIC_PASSPHRASE); + String symmetricPassphrase = data.getString(ENCRYPT_SYMMETRIC_PASSPHRASE); boolean useAsciiArmor = data.getBoolean(ENCRYPT_USE_ASCII_ARMOR); long encryptionKeyIds[] = data.getLongArray(ENCRYPT_ENCRYPTION_KEYS_IDS); @@ -329,7 +329,7 @@ public class KeychainIntentService extends IntentService Preferences.getPreferences(this).getDefaultEncryptionAlgorithm()) .signatureForceV3(Preferences.getPreferences(this).getForceV3Signatures()) .encryptionKeyIds(encryptionKeyIds) - .encryptionPassphrase(encryptionPassphrase) + .symmetricPassphrase(symmetricPassphrase) .signatureKeyId(secretKeyId) .signatureHashAlgorithm( Preferences.getPreferences(this).getDefaultHashAlgorithm()) diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 47c4347f6..db35b7c28 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -71,18 +71,12 @@ public class EncryptActivity extends DrawerActivity implements private static final int PAGER_CONTENT_MESSAGE = 0; private static final int PAGER_CONTENT_FILE = 1; - // model + // model useb by message and file fragment private long mEncryptionKeyIds[] = null; private long mSigningKeyId = Id.key.none; private String mPassphrase; private String mPassphraseAgain; - private boolean mAsciiArmorDemand = false; - private boolean mOverrideAsciiArmor = false; - - private boolean mGenerateSignature = false; - - @Override public void onSigningKeySelected(long signingKeyId) { mSigningKeyId = signingKeyId; @@ -208,8 +202,8 @@ public class EncryptActivity extends DrawerActivity implements } if (extras.containsKey(EXTRA_ASCII_ARMOR)) { - mAsciiArmorDemand = extras.getBoolean(EXTRA_ASCII_ARMOR, true); - mFileFragmentBundle.putBoolean(EncryptFileFragment.ARG_ASCII_ARMOR, mAsciiArmorDemand); + boolean requestAsciiArmor = extras.getBoolean(EXTRA_ASCII_ARMOR, true); + mFileFragmentBundle.putBoolean(EncryptFileFragment.ARG_ASCII_ARMOR, requestAsciiArmor); } String textData = extras.getString(EXTRA_TEXT); @@ -252,51 +246,4 @@ public class EncryptActivity extends DrawerActivity implements } } - -// /** -// * Update ActionBar buttons based on current selection in view -// */ -// private void updateActionBarButtons() { -// switch (mSource.getCurrentView().getId()) { -// case R.id.sourceFile: { -// mEncryptShare.setVisibility(View.GONE); -// mEncryptClipboard.setVisibility(View.GONE); -// mEncryptFile.setVisibility(View.VISIBLE); -// break; -// } -// -// case R.id.sourceMessage: { -// mSourceLabel.setText(R.string.label_message); -// -// mEncryptShare.setVisibility(View.VISIBLE); -// mEncryptClipboard.setVisibility(View.VISIBLE); -// mEncryptFile.setVisibility(View.GONE); -// -// if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { -// mEncryptShare.setEnabled(true); -// mEncryptClipboard.setEnabled(true); -// } else { -// if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { -// if (mSecretKeyId == 0) { -// mEncryptShare.setEnabled(false); -// mEncryptClipboard.setEnabled(false); -// } else { -// mEncryptShare.setEnabled(true); -// mEncryptClipboard.setEnabled(true); -// } -// } else { -// mEncryptShare.setEnabled(true); -// mEncryptClipboard.setEnabled(true); -// } -// } -// break; -// } -// -// default: { -// break; -// } -// } -// -// } - } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java index 8fbabe9c0..0786b3a16 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java @@ -1,5 +1,21 @@ -package org.sufficientlysecure.keychain.ui; +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ +package org.sufficientlysecure.keychain.ui; public interface EncryptActivityInterface { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index b88dafd4a..72087f9bd 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -79,15 +79,16 @@ public class EncryptAsymmetricFragment extends Fragment { private void setSignatureKeyId(long signatureKeyId) { mSecretKeyId = signatureKeyId; + // update key selection in EncryptActivity mKeySelectionListener.onSigningKeySelected(signatureKeyId); } private void setEncryptionKeyIds(long[] encryptionKeyIds) { mEncryptionKeyIds = encryptionKeyIds; + // update key selection in EncryptActivity mKeySelectionListener.onEncryptionKeysSelected(encryptionKeyIds); } - /** * Inflate the layout for this fragment */ @@ -138,6 +139,7 @@ public class EncryptAsymmetricFragment extends Fragment { */ private void preselectKeys(long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds) { if (preselectedSignatureKeyId != 0) { + // TODO: don't use bouncy castle objects! PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(getActivity(), preselectedSignatureKeyId); PGPSecretKey masterKey; @@ -155,6 +157,8 @@ public class EncryptAsymmetricFragment extends Fragment { if (preselectedEncryptionKeyIds != null) { Vector goodIds = new Vector(); for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) { + // TODO: don't use bouncy castle objects! + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(getActivity(), preselectedEncryptionKeyIds[i]); PGPPublicKey masterKey; @@ -197,7 +201,7 @@ public class EncryptAsymmetricFragment extends Fragment { } else { String uid = getResources().getString(R.string.user_id_no_name); String uidExtra = ""; - // TODO: make it nice and use helper! + // TODO: don't use bouncy castle objects! PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(getActivity(), mSecretKeyId); if (keyRing != null) { @@ -215,9 +219,6 @@ public class EncryptAsymmetricFragment extends Fragment { mMainUserIdRest.setText(uidExtra); mSign.setChecked(true); } - -//TODO -// updateActionBarButtons(); } private void selectPublicKeys() { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java index 734941ca7..a2cd74378 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java @@ -223,29 +223,30 @@ public class EncryptFileFragment extends Fragment { if (mEncryptInterface.isModeSymmetric()) { // symmetric encryption - if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) { - AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show(); - return; - } - - boolean gotPassPhrase = (mEncryptInterface.getPassphrase().length() != 0); + boolean gotPassPhrase = (mEncryptInterface.getPassphrase() != null + && mEncryptInterface.getPassphrase().length() != 0); if (!gotPassPhrase) { AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT) .show(); return; } + + if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) { + AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show(); + return; + } } else { // asymmetric encryption - boolean encryptIt = (mEncryptInterface.getEncryptionKeys() != null + boolean gotEncryptionKeys = (mEncryptInterface.getEncryptionKeys() != null && mEncryptInterface.getEncryptionKeys().length > 0); - // for now require at least one form of encryption for files - if (!encryptIt) { + + if (!gotEncryptionKeys) { AppMsg.makeText(getActivity(), R.string.select_encryption_key, AppMsg.STYLE_ALERT).show(); return; } - if (!encryptIt && mEncryptInterface.getSignatureKey() == 0) { + if (!gotEncryptionKeys && mEncryptInterface.getSignatureKey() == 0) { AppMsg.makeText(getActivity(), R.string.select_encryption_or_signature_key, AppMsg.STYLE_ALERT).show(); return; @@ -266,14 +267,12 @@ public class EncryptFileFragment extends Fragment { // Send all information needed to service to edit key in other thread Intent intent = new Intent(getActivity(), KeychainIntentService.class); + intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN); + // fill values for this action Bundle data = new Bundle(); - boolean useAsciiArmor = true; - long encryptionKeyIds[] = null; - int compressionId = 0; - boolean signOnly = false; - long mSecretKeyIdToPass = 0; + data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI); if (mEncryptInterface.isModeSymmetric()) { Log.d(Constants.TAG, "Symmetric encryption enabled!"); @@ -281,35 +280,28 @@ public class EncryptFileFragment extends Fragment { if (passphrase.length() == 0) { passphrase = null; } - data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase); + data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase); } else { - mSecretKeyIdToPass = mEncryptInterface.getSignatureKey(); - encryptionKeyIds = mEncryptInterface.getEncryptionKeys(); - signOnly = (mEncryptInterface.getEncryptionKeys() == null + data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mEncryptInterface.getSignatureKey()); + data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptInterface.getEncryptionKeys()); + + boolean signOnly = (mEncryptInterface.getEncryptionKeys() == null || mEncryptInterface.getEncryptionKeys().length == 0); + data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly); } - intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN); - - // choose default settings, target and data bundle by target - useAsciiArmor = mAsciiArmor.isChecked(); - compressionId = ((Choice) mFileCompression.getSelectedItem()).getId(); - - data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI); - Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" + mOutputFilename); data.putString(KeychainIntentService.ENCRYPT_INPUT_FILE, mInputFilename); data.putString(KeychainIntentService.ENCRYPT_OUTPUT_FILE, mOutputFilename); - - data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyIdToPass); + boolean useAsciiArmor = mAsciiArmor.isChecked(); data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, useAsciiArmor); - data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, encryptionKeyIds); + + int compressionId = ((Choice) mFileCompression.getSelectedItem()).getId(); data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId); // data.putBoolean(KeychainIntentService.ENCRYPT_GENERATE_SIGNATURE, mGenerateSignature); - data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java index 7f1d7311d..6fdf9c034 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java @@ -125,25 +125,26 @@ public class EncryptMessageFragment extends Fragment { if (mEncryptInterface.isModeSymmetric()) { // symmetric encryption - boolean gotPassPhrase = false; - if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) { - AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show(); - return; - } - - gotPassPhrase = (mEncryptInterface.getPassphrase().length() != 0); + boolean gotPassPhrase = (mEncryptInterface.getPassphrase() != null + && mEncryptInterface.getPassphrase().length() != 0); if (!gotPassPhrase) { AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT) .show(); return; } + + if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) { + AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show(); + return; + } + } else { // asymmetric encryption - boolean encryptIt = (mEncryptInterface.getEncryptionKeys() != null + boolean gotEncryptionKeys = (mEncryptInterface.getEncryptionKeys() != null && mEncryptInterface.getEncryptionKeys().length > 0); - if (!encryptIt && mEncryptInterface.getSignatureKey() == 0) { + if (!gotEncryptionKeys && mEncryptInterface.getSignatureKey() == 0) { AppMsg.makeText(getActivity(), R.string.select_encryption_or_signature_key, AppMsg.STYLE_ALERT).show(); return; @@ -164,13 +165,14 @@ public class EncryptMessageFragment extends Fragment { // Send all information needed to service to edit key in other thread Intent intent = new Intent(getActivity(), KeychainIntentService.class); + intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN); + // fill values for this action Bundle data = new Bundle(); - long encryptionKeyIds[] = null; - int compressionId = 0; - boolean signOnly = false; - long mSecretKeyIdToPass = 0; + data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); + + String message = mMessage.getText().toString(); if (mEncryptInterface.isModeSymmetric()) { Log.d(Constants.TAG, "Symmetric encryption enabled!"); @@ -178,33 +180,26 @@ public class EncryptMessageFragment extends Fragment { if (passphrase.length() == 0) { passphrase = null; } - data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase); + data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase); } else { - mSecretKeyIdToPass = mEncryptInterface.getSignatureKey(); - encryptionKeyIds = mEncryptInterface.getEncryptionKeys(); - signOnly = (mEncryptInterface.getEncryptionKeys() == null + data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mEncryptInterface.getSignatureKey()); + data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptInterface.getEncryptionKeys()); + + boolean signOnly = (mEncryptInterface.getEncryptionKeys() == null || mEncryptInterface.getEncryptionKeys().length == 0); + data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly); + if (signOnly) { + message = fixBadCharactersForGmail(message); + } } - intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN); - - // choose default settings, target and data bundle by target - compressionId = Preferences.getPreferences(getActivity()).getDefaultMessageCompression(); - - data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); - - String message = mMessage.getText().toString(); - if (signOnly) { - message = fixBadCharactersForGmail(message); - } data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, message.getBytes()); - data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyIdToPass); data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, true); - data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, encryptionKeyIds); + + int compressionId = Preferences.getPreferences(getActivity()).getDefaultMessageCompression(); data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId); // data.putBoolean(KeychainIntentService.ENCRYPT_GENERATE_SIGNATURE, mGenerateSignature); - data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java index f23cc565a..8efa07953 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java @@ -73,6 +73,7 @@ public class EncryptSymmetricFragment extends Fragment { @Override public void afterTextChanged(Editable s) { + // update passphrase in EncryptActivity mPassphraseUpdateListener.onPassphraseUpdate(s.toString()); } }); @@ -87,6 +88,7 @@ public class EncryptSymmetricFragment extends Fragment { @Override public void afterTextChanged(Editable s) { + // update passphrase in EncryptActivity mPassphraseUpdateListener.onPassphraseAgainUpdate(s.toString()); } }); -- cgit v1.2.3 From 866d2d28cc225389a6ff6ef78616b72926d41a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 14:25:37 +0200 Subject: Simplify encrypt and sign backend --- .../keychain/service/KeychainIntentService.java | 152 ++++++++------------- .../keychain/ui/EncryptFileFragment.java | 10 +- .../keychain/ui/EncryptMessageFragment.java | 12 +- 3 files changed, 59 insertions(+), 115 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 46033d094..2ad7e348b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -18,7 +18,6 @@ package org.sufficientlysecure.keychain.service; import android.app.IntentService; -import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -36,7 +35,6 @@ import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.pgp.*; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; import org.sufficientlysecure.keychain.util.*; @@ -88,12 +86,10 @@ public class KeychainIntentService extends IntentService public static final int TARGET_STREAM = 3; // encrypt - public static final String ENCRYPT_SECRET_KEY_ID = "secret_key_id"; + public static final String ENCRYPT_SIGNATURE_KEY_ID = "secret_key_id"; public static final String ENCRYPT_USE_ASCII_ARMOR = "use_ascii_armor"; public static final String ENCRYPT_ENCRYPTION_KEYS_IDS = "encryption_keys_ids"; public static final String ENCRYPT_COMPRESSION_ID = "compression_id"; - public static final String ENCRYPT_GENERATE_SIGNATURE = "generate_signature"; - public static final String ENCRYPT_SIGN_ONLY = "sign_only"; public static final String ENCRYPT_MESSAGE_BYTES = "message_bytes"; public static final String ENCRYPT_INPUT_FILE = "input_file"; public static final String ENCRYPT_OUTPUT_FILE = "output_file"; @@ -152,7 +148,7 @@ public class KeychainIntentService extends IntentService public static final String RESULT_SIGNATURE_BYTES = "signature_data"; public static final String RESULT_SIGNATURE_STRING = "signature_text"; public static final String RESULT_ENCRYPTED_STRING = "encrypted_message"; - public static final String RESULT_ENCRYPTED_BYTES = "encrypted_data"; + public static final String RESULT_BYTES = "encrypted_data"; public static final String RESULT_URI = "result_uri"; // decrypt/verify @@ -220,20 +216,17 @@ public class KeychainIntentService extends IntentService /* Input */ int target = data.getInt(TARGET); - long secretKeyId = data.getLong(ENCRYPT_SECRET_KEY_ID); + long signatureKeyId = data.getLong(ENCRYPT_SIGNATURE_KEY_ID); String symmetricPassphrase = data.getString(ENCRYPT_SYMMETRIC_PASSPHRASE); boolean useAsciiArmor = data.getBoolean(ENCRYPT_USE_ASCII_ARMOR); long encryptionKeyIds[] = data.getLongArray(ENCRYPT_ENCRYPTION_KEYS_IDS); int compressionId = data.getInt(ENCRYPT_COMPRESSION_ID); - boolean generateSignature = data.getBoolean(ENCRYPT_GENERATE_SIGNATURE); - boolean signOnly = data.getBoolean(ENCRYPT_SIGN_ONLY); - - InputStream inStream = null; - long inLength = -1; - InputData inputData = null; - OutputStream outStream = null; - String streamFilename = null; + InputStream inStream; + long inLength; + InputData inputData; + OutputStream outStream; +// String streamFilename = null; switch (target) { case TARGET_BYTES: /* encrypting bytes directly */ byte[] bytes = data.getByteArray(ENCRYPT_MESSAGE_BYTES); @@ -265,29 +258,30 @@ public class KeychainIntentService extends IntentService break; - case TARGET_STREAM: /* Encrypting stream from content uri */ - Uri providerUri = (Uri) data.getParcelable(ENCRYPT_PROVIDER_URI); - - // InputStream - InputStream in = getContentResolver().openInputStream(providerUri); - inLength = PgpHelper.getLengthOfStream(in); - inputData = new InputData(in, inLength); - - // OutputStream - try { - while (true) { - streamFilename = PgpHelper.generateRandomFilename(32); - if (streamFilename == null) { - throw new PgpGeneralException("couldn't generate random file name"); - } - openFileInput(streamFilename).close(); - } - } catch (FileNotFoundException e) { - // found a name that isn't used yet - } - outStream = openFileOutput(streamFilename, Context.MODE_PRIVATE); - - break; + // TODO: not used currently +// case TARGET_STREAM: /* Encrypting stream from content uri */ +// Uri providerUri = (Uri) data.getParcelable(ENCRYPT_PROVIDER_URI); +// +// // InputStream +// InputStream in = getContentResolver().openInputStream(providerUri); +// inLength = PgpHelper.getLengthOfStream(in); +// inputData = new InputData(in, inLength); +// +// // OutputStream +// try { +// while (true) { +// streamFilename = PgpHelper.generateRandomFilename(32); +// if (streamFilename == null) { +// throw new PgpGeneralException("couldn't generate random file name"); +// } +// openFileInput(streamFilename).close(); +// } +// } catch (FileNotFoundException e) { +// // found a name that isn't used yet +// } +// outStream = openFileOutput(streamFilename, Context.MODE_PRIVATE); +// +// break; default: throw new PgpGeneralException("No target choosen!"); @@ -299,45 +293,20 @@ public class KeychainIntentService extends IntentService new PgpSignEncrypt.Builder(this, inputData, outStream); builder.progress(this); - if (generateSignature) { - Log.d(Constants.TAG, "generating signature..."); - builder.enableAsciiArmorOutput(useAsciiArmor) - .signatureForceV3(Preferences.getPreferences(this).getForceV3Signatures()) - .signatureKeyId(secretKeyId) - .signatureHashAlgorithm( - Preferences.getPreferences(this).getDefaultHashAlgorithm()) - .signaturePassphrase( - PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); - - builder.build().generateSignature(); - } else if (signOnly) { - Log.d(Constants.TAG, "sign only..."); - builder.enableAsciiArmorOutput(useAsciiArmor) - .signatureForceV3(Preferences.getPreferences(this).getForceV3Signatures()) - .signatureKeyId(secretKeyId) - .signatureHashAlgorithm( - Preferences.getPreferences(this).getDefaultHashAlgorithm()) - .signaturePassphrase( - PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); - - builder.build().execute(); - } else { - Log.d(Constants.TAG, "encrypt..."); - builder.enableAsciiArmorOutput(useAsciiArmor) - .compressionId(compressionId) - .symmetricEncryptionAlgorithm( - Preferences.getPreferences(this).getDefaultEncryptionAlgorithm()) - .signatureForceV3(Preferences.getPreferences(this).getForceV3Signatures()) - .encryptionKeyIds(encryptionKeyIds) - .symmetricPassphrase(symmetricPassphrase) - .signatureKeyId(secretKeyId) - .signatureHashAlgorithm( - Preferences.getPreferences(this).getDefaultHashAlgorithm()) - .signaturePassphrase( - PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); - - builder.build().execute(); - } + builder.enableAsciiArmorOutput(useAsciiArmor) + .compressionId(compressionId) + .symmetricEncryptionAlgorithm( + Preferences.getPreferences(this).getDefaultEncryptionAlgorithm()) + .signatureForceV3(Preferences.getPreferences(this).getForceV3Signatures()) + .encryptionKeyIds(encryptionKeyIds) + .symmetricPassphrase(symmetricPassphrase) + .signatureKeyId(signatureKeyId) + .signatureHashAlgorithm( + Preferences.getPreferences(this).getDefaultHashAlgorithm()) + .signaturePassphrase( + PassphraseCacheService.getCachedPassphrase(this, signatureKeyId)); + + builder.build().execute(); outStream.close(); @@ -347,33 +316,20 @@ public class KeychainIntentService extends IntentService switch (target) { case TARGET_BYTES: - if (useAsciiArmor) { - String output = new String( - ((ByteArrayOutputStream) outStream).toByteArray()); - if (generateSignature) { - resultData.putString(RESULT_SIGNATURE_STRING, output); - } else { - resultData.putString(RESULT_ENCRYPTED_STRING, output); - } - } else { - byte output[] = ((ByteArrayOutputStream) outStream).toByteArray(); - if (generateSignature) { - resultData.putByteArray(RESULT_SIGNATURE_BYTES, output); - } else { - resultData.putByteArray(RESULT_ENCRYPTED_BYTES, output); - } - } + byte output[] = ((ByteArrayOutputStream) outStream).toByteArray(); + + resultData.putByteArray(RESULT_BYTES, output); break; case TARGET_URI: // nothing, file was written, just send okay break; - case TARGET_STREAM: - String uri = DataStream.buildDataStreamUri(streamFilename).toString(); - resultData.putString(RESULT_URI, uri); - - break; +// case TARGET_STREAM: +// String uri = DataStream.buildDataStreamUri(streamFilename).toString(); +// resultData.putString(RESULT_URI, uri); +// +// break; } OtherHelper.logDebugBundle(resultData, "resultData"); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java index a2cd74378..fb727d297 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java @@ -282,12 +282,8 @@ public class EncryptFileFragment extends Fragment { } data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase); } else { - data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mEncryptInterface.getSignatureKey()); + data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID, mEncryptInterface.getSignatureKey()); data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptInterface.getEncryptionKeys()); - - boolean signOnly = (mEncryptInterface.getEncryptionKeys() == null - || mEncryptInterface.getEncryptionKeys().length == 0); - data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly); } Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" @@ -313,10 +309,6 @@ public class EncryptFileFragment extends Fragment { super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { - // get returned data bundle - Bundle data = message.getData(); - - String output; AppMsg.makeText(getActivity(), R.string.encryption_successful, AppMsg.STYLE_INFO).show(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java index 6fdf9c034..f2187dac3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java @@ -182,12 +182,11 @@ public class EncryptMessageFragment extends Fragment { } data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase); } else { - data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mEncryptInterface.getSignatureKey()); + data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID, mEncryptInterface.getSignatureKey()); data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptInterface.getEncryptionKeys()); boolean signOnly = (mEncryptInterface.getEncryptionKeys() == null || mEncryptInterface.getEncryptionKeys().length == 0); - data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly); if (signOnly) { message = fixBadCharactersForGmail(message); } @@ -214,18 +213,15 @@ public class EncryptMessageFragment extends Fragment { // get returned data bundle Bundle data = message.getData(); - String output; + String output = new String(data.getByteArray(KeychainIntentService.RESULT_BYTES)); + Log.d(Constants.TAG, "output: " + output); + if (toClipboard) { - output = data.getString(KeychainIntentService.RESULT_ENCRYPTED_STRING); - Log.d(Constants.TAG, "output: " + output); ClipboardReflection.copyToClipboard(getActivity(), output); AppMsg.makeText(getActivity(), R.string.encryption_to_clipboard_successful, AppMsg.STYLE_INFO) .show(); } else { - output = data.getString(KeychainIntentService.RESULT_ENCRYPTED_STRING); - Log.d(Constants.TAG, "output: " + output); - Intent sendIntent = new Intent(Intent.ACTION_SEND); // Type is set to text/plain so that encrypted messages can -- cgit v1.2.3 From ef562b5e202470022b78e3ba72997ebbc90171fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 15:04:54 +0200 Subject: Fix layouts --- .../org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index 72087f9bd..b38369dcc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -26,6 +26,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; +import android.widget.LinearLayout; import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; -- cgit v1.2.3 From fadc08480fdad9bfa672ef4821af4d0c82ef076b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 15:40:07 +0200 Subject: Fix pre-selection for encrypt --- .../sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index b38369dcc..5b7f9e4cc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -26,7 +26,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; -import android.widget.LinearLayout; import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; @@ -82,12 +81,14 @@ public class EncryptAsymmetricFragment extends Fragment { mSecretKeyId = signatureKeyId; // update key selection in EncryptActivity mKeySelectionListener.onSigningKeySelected(signatureKeyId); + updateView(); } private void setEncryptionKeyIds(long[] encryptionKeyIds) { mEncryptionKeyIds = encryptionKeyIds; // update key selection in EncryptActivity mKeySelectionListener.onEncryptionKeysSelected(encryptionKeyIds); + updateView(); } /** @@ -113,7 +114,6 @@ public class EncryptAsymmetricFragment extends Fragment { selectSecretKey(); } else { setSignatureKeyId(Id.key.none); - updateView(); } } }); @@ -259,7 +259,6 @@ public class EncryptAsymmetricFragment extends Fragment { setEncryptionKeyIds(bundle .getLongArray(SelectPublicKeyActivity.RESULT_EXTRA_MASTER_KEY_IDS)); } - updateView(); break; } @@ -270,7 +269,6 @@ public class EncryptAsymmetricFragment extends Fragment { } else { setSignatureKeyId(Id.key.none); } - updateView(); break; } -- cgit v1.2.3 From ebb7f559216fd2f4d82f824e4fa7ceddbfa7cd1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 16:08:40 +0200 Subject: Fix symmetric decryption --- .../keychain/pgp/PgpDecryptVerify.java | 219 ++++++++++----------- .../keychain/remote/OpenPgpService.java | 5 +- .../keychain/service/KeychainIntentService.java | 4 +- .../keychain/ui/DecryptFileFragment.java | 3 + .../keychain/ui/DecryptMessageFragment.java | 3 + 5 files changed, 117 insertions(+), 117 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index d06898c89..741c1323a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -18,16 +18,38 @@ package org.sufficientlysecure.keychain.pgp; import android.content.Context; + import org.openintents.openpgp.OpenPgpSignatureResult; import org.spongycastle.bcpg.ArmoredInputStream; import org.spongycastle.bcpg.SignatureSubpacketTags; -import org.spongycastle.openpgp.*; +import org.spongycastle.openpgp.PGPCompressedData; +import org.spongycastle.openpgp.PGPEncryptedData; +import org.spongycastle.openpgp.PGPEncryptedDataList; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPLiteralData; +import org.spongycastle.openpgp.PGPObjectFactory; +import org.spongycastle.openpgp.PGPOnePassSignature; +import org.spongycastle.openpgp.PGPOnePassSignatureList; +import org.spongycastle.openpgp.PGPPBEEncryptedData; +import org.spongycastle.openpgp.PGPPrivateKey; +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.PGPPublicKeyEncryptedData; +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.spongycastle.openpgp.PGPSignature; +import org.spongycastle.openpgp.PGPSignatureList; +import org.spongycastle.openpgp.PGPSignatureSubpacketVector; import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider; import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory; -import org.spongycastle.openpgp.operator.jcajce.*; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; @@ -37,7 +59,12 @@ import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; -import java.io.*; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.security.SignatureException; import java.util.Iterator; @@ -50,7 +77,7 @@ public class PgpDecryptVerify { private OutputStream mOutStream; private ProgressDialogUpdater mProgressDialogUpdater; - private boolean mAssumeSymmetric; + private boolean mAllowSymmetricDecryption; private String mPassphrase; private long mEnforcedKeyId; @@ -61,7 +88,7 @@ public class PgpDecryptVerify { this.mOutStream = builder.mOutStream; this.mProgressDialogUpdater = builder.mProgressDialogUpdater; - this.mAssumeSymmetric = builder.mAssumeSymmetric; + this.mAllowSymmetricDecryption = builder.mAllowSymmetricDecryption; this.mPassphrase = builder.mPassphrase; this.mEnforcedKeyId = builder.mEnforcedKeyId; } @@ -74,7 +101,7 @@ public class PgpDecryptVerify { // optional private ProgressDialogUpdater mProgressDialogUpdater = null; - private boolean mAssumeSymmetric = false; + private boolean mAllowSymmetricDecryption = false; private String mPassphrase = null; private long mEnforcedKeyId = 0; @@ -89,8 +116,8 @@ public class PgpDecryptVerify { return this; } - public Builder assumeSymmetric(boolean assumeSymmetric) { - this.mAssumeSymmetric = assumeSymmetric; + public Builder allowSymmetricDecryption(boolean allowSymmetricDecryption) { + this.mAllowSymmetricDecryption = allowSymmetricDecryption; return this; } @@ -128,35 +155,6 @@ public class PgpDecryptVerify { } } - public static boolean hasSymmetricEncryption(Context context, InputStream inputStream) - throws PgpGeneralException, IOException { - InputStream in = PGPUtil.getDecoderStream(inputStream); - 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 PgpGeneralException(context.getString(R.string.error_invalid_data)); - } - - Iterator it = enc.getEncryptedDataObjects(); - while (it.hasNext()) { - Object obj = it.next(); - if (obj instanceof PGPPBEEncryptedData) { - return true; - } - } - - return false; - } - /** * Decrypts and/or verifies data based on parameters of class * @@ -221,25 +219,78 @@ public class PgpDecryptVerify { currentProgress += 5; - // TODO: currently we always only look at the first known key or symmetric encryption, - // there might be more... - if (mAssumeSymmetric) { - PGPPBEEncryptedData pbe = null; - Iterator it = enc.getEncryptedDataObjects(); - // find secret key - while (it.hasNext()) { - Object obj = it.next(); - if (obj instanceof PGPPBEEncryptedData) { - pbe = (PGPPBEEncryptedData) obj; + PGPPublicKeyEncryptedData encryptedDataAsymmetric = null; + PGPPBEEncryptedData encryptedDataSymmetric = null; + PGPSecretKey secretKey = null; + Iterator it = enc.getEncryptedDataObjects(); + boolean symmetricPacketFound = false; + // find secret key + while (it.hasNext()) { + Object obj = it.next(); + if (obj instanceof PGPPublicKeyEncryptedData) { + updateProgress(R.string.progress_finding_key, currentProgress, 100); + + PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; + secretKey = ProviderHelper.getPGPSecretKeyByKeyId(mContext, encData.getKeyID()); + if (secretKey != null) { + // secret key exists in database + + // allow only a specific key for decryption? + if (mEnforcedKeyId != 0) { + // TODO: improve this code! get master key directly! + PGPSecretKeyRing secretKeyRing = + ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, encData.getKeyID()); + long masterKeyId = PgpKeyHelper.getMasterKey(secretKeyRing).getKeyID(); + Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID()); + Log.d(Constants.TAG, "enforcedKeyId: " + mEnforcedKeyId); + Log.d(Constants.TAG, "masterKeyId: " + masterKeyId); + + if (mEnforcedKeyId != masterKeyId) { + throw new PgpGeneralException( + mContext.getString(R.string.error_no_secret_key_found)); + } + } + + encryptedDataAsymmetric = encData; + + // if no passphrase was explicitly set try to get it from the cache service + if (mPassphrase == null) { + // returns "" if key has no passphrase + mPassphrase = + PassphraseCacheService.getCachedPassphrase(mContext, encData.getKeyID()); + + // if passphrase was not cached, return here + // indicating that a passphrase is missing! + if (mPassphrase == null) { + returnData.setKeyIdPassphraseNeeded(encData.getKeyID()); + returnData.setStatus(PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED); + return returnData; + } + } + + // break out of while, only get first object here + // TODO???: There could be more pgp objects, which are not decrypted! break; } - } + } else if (mAllowSymmetricDecryption && obj instanceof PGPPBEEncryptedData) { + symmetricPacketFound = true; - if (pbe == null) { - throw new PgpGeneralException( - mContext.getString(R.string.error_no_symmetric_encryption_packet)); + encryptedDataSymmetric = (PGPPBEEncryptedData) obj; + + // if no passphrase is given, return here + // indicating that a passphrase is missing! + if (mPassphrase == null) { + returnData.setStatus(PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED); + return returnData; + } + + // break out of while, only get first object here + // TODO???: There could be more pgp objects, which are not decrypted! + break; } + } + if (symmetricPacketFound) { updateProgress(R.string.progress_preparing_streams, currentProgress, 100); PGPDigestCalculatorProvider digestCalcProvider = new JcaPGPDigestCalculatorProviderBuilder() @@ -248,65 +299,11 @@ public class PgpDecryptVerify { digestCalcProvider).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( mPassphrase.toCharArray()); - clear = pbe.getDataStream(decryptorFactory); + clear = encryptedDataSymmetric.getDataStream(decryptorFactory); - encryptedData = pbe; + encryptedData = encryptedDataSymmetric; currentProgress += 5; } else { - PGPPublicKeyEncryptedData pbe = null; - PGPSecretKey secretKey = null; - Iterator it = enc.getEncryptedDataObjects(); - // find secret key - while (it.hasNext()) { - Object obj = it.next(); - if (obj instanceof PGPPublicKeyEncryptedData) { - updateProgress(R.string.progress_finding_key, currentProgress, 100); - - PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; - secretKey = ProviderHelper.getPGPSecretKeyByKeyId(mContext, encData.getKeyID()); - if (secretKey != null) { - // secret key exists in database - - // allow only a specific key for decryption? - if (mEnforcedKeyId != 0) { - // TODO: improve this code! get master key directly! - PGPSecretKeyRing secretKeyRing = - ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, encData.getKeyID()); - long masterKeyId = PgpKeyHelper.getMasterKey(secretKeyRing).getKeyID(); - Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID()); - Log.d(Constants.TAG, "enforcedKeyId: " + mEnforcedKeyId); - Log.d(Constants.TAG, "masterKeyId: " + masterKeyId); - - if (mEnforcedKeyId != masterKeyId) { - throw new PgpGeneralException( - mContext.getString(R.string.error_no_secret_key_found)); - } - } - - pbe = encData; - - // if no passphrase was explicitly set try to get it from the cache service - if (mPassphrase == null) { - // returns "" if key has no passphrase - mPassphrase = - PassphraseCacheService.getCachedPassphrase(mContext, encData.getKeyID()); - - // if passphrase was not cached, return here - // indicating that a passphrase is missing! - if (mPassphrase == null) { - returnData.setKeyIdPassphraseNeeded(encData.getKeyID()); - returnData.setStatus(PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED); - return returnData; - } - } - - break; - } - } else if (obj instanceof PGPPBEEncryptedData) { - - } - } - if (secretKey == null) { throw new PgpGeneralException(mContext.getString(R.string.error_no_secret_key_found)); } @@ -332,9 +329,9 @@ public class PgpDecryptVerify { PublicKeyDataDecryptorFactory decryptorFactory = new JcePublicKeyDataDecryptorFactoryBuilder() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(privateKey); - clear = pbe.getDataStream(decryptorFactory); + clear = encryptedDataAsymmetric.getDataStream(decryptorFactory); - encryptedData = pbe; + encryptedData = encryptedDataAsymmetric; currentProgress += 5; } @@ -389,7 +386,7 @@ public class PgpDecryptVerify { if (signature != null) { JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); signature.init(contentVerifierBuilderProvider, signatureKey); } else { @@ -686,7 +683,7 @@ public class PgpDecryptVerify { } private static boolean verifyPrimaryKeyBinding(PGPSignatureSubpacketVector pkts, - PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { + PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { boolean validPrimaryKeyBinding = false; JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 1d3bb88df..1cd5862e7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -290,9 +290,8 @@ public class OpenPgpService extends RemoteService { InputData inputData = new InputData(is, inputLength); PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os); - builder.assumeSymmetric(false) // no support for symmetric encryption - // allow only the private key for this app for decryption - .enforcedKeyId(accSettings.getKeyId()) + builder.allowSymmetricDecryption(false) // no support for symmetric encryption + .enforcedKeyId(accSettings.getKeyId()) // allow only the private key for this app for decryption .passphrase(passphrase); // TODO: currently does not support binary signed-only content diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 2ad7e348b..2060c6f61 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -98,7 +98,6 @@ public class KeychainIntentService extends IntentService // decrypt/verify public static final String DECRYPT_CIPHERTEXT_BYTES = "ciphertext_bytes"; - public static final String DECRYPT_ASSUME_SYMMETRIC = "assume_symmetric"; public static final String DECRYPT_PASSPHRASE = "passphrase"; // save keyring @@ -344,7 +343,6 @@ public class KeychainIntentService extends IntentService int target = data.getInt(TARGET); byte[] bytes = data.getByteArray(DECRYPT_CIPHERTEXT_BYTES); - boolean assumeSymmetricEncryption = data.getBoolean(DECRYPT_ASSUME_SYMMETRIC); String passphrase = data.getString(DECRYPT_PASSPHRASE); InputStream inStream; @@ -424,7 +422,7 @@ public class KeychainIntentService extends IntentService PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, outStream); builder.progressDialogUpdater(this); - builder.assumeSymmetric(assumeSymmetricEncryption) + builder.allowSymmetricDecryption(true) .passphrase(passphrase); PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index a929047b8..cec6d7a59 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -35,6 +35,7 @@ import com.devspark.appmsg.AppMsg; import org.openintents.openpgp.OpenPgpSignatureResult; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; @@ -202,6 +203,8 @@ public class DecryptFileFragment extends DecryptFragment { if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded()); + } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { + showPassphraseDialog(Id.key.symmetric); } else { if (mDeleteAfter.isChecked()) { // Create and show dialog to delete original file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java index 94034b356..197a2af04 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java @@ -33,6 +33,7 @@ import com.devspark.appmsg.AppMsg; import org.openintents.openpgp.OpenPgpSignatureResult; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; @@ -149,6 +150,8 @@ public class DecryptMessageFragment extends DecryptFragment { if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded()); + } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { + showPassphraseDialog(Id.key.symmetric); } else { AppMsg.makeText(getActivity(), R.string.decryption_successful, AppMsg.STYLE_INFO).show(); -- cgit v1.2.3 From 6f36b72eee8ed2a0baa768e696bbb6e9632ed795 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 22 Mar 2014 13:04:31 +0100 Subject: PgpKeyOperation: factor out all android dependencies Conflicts: OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java --- .../keychain/pgp/PgpKeyOperation.java | 216 +++++++++++---------- .../pgp/exception/PgpGeneralException.java | 3 + .../pgp/exception/PgpGeneralMsgIdException.java | 35 ++++ .../keychain/service/KeychainIntentService.java | 47 ++++- .../keychain/util/ProgressScaler.java | 50 +++++ 5 files changed, 235 insertions(+), 116 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 592bdec73..520189448 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -17,20 +17,6 @@ package org.sufficientlysecure.keychain.pgp; -import java.io.IOException; -import java.math.BigInteger; -import java.security.InvalidAlgorithmParameterException; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.SecureRandom; -import java.security.SignatureException; -import java.util.ArrayList; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Iterator; -import java.util.TimeZone; -import android.content.Context; import org.spongycastle.bcpg.CompressionAlgorithmTags; import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; @@ -46,18 +32,11 @@ import org.spongycastle.openpgp.operator.jcajce.*; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.util.Primes; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; - -import android.content.Context; -import android.util.Pair; import org.sufficientlysecure.keychain.util.IterableIterator; -import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.Primes; -import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; import java.io.IOException; import java.math.BigInteger; @@ -69,9 +48,17 @@ import java.util.Iterator; import java.util.List; import java.util.TimeZone; +/** This class is the single place where ALL operations that actually modify a PGP public or secret + * key take place. + * + * Note that no android specific stuff should be done here, ie no imports from com.android. + * + * All operations support progress reporting to a ProgressDialogUpdater passed on initialization. + * This indicator may be null. + * + */ public class PgpKeyOperation { - private final Context mContext; - private final ProgressDialogUpdater mProgress; + private ProgressDialogUpdater mProgress; private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[]{ SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, @@ -83,9 +70,8 @@ public class PgpKeyOperation { CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2, CompressionAlgorithmTags.ZIP}; - public PgpKeyOperation(Context context, ProgressDialogUpdater progress) { + public PgpKeyOperation(ProgressDialogUpdater progress) { super(); - this.mContext = context; this.mProgress = progress; } @@ -101,13 +87,29 @@ public class PgpKeyOperation { } } + /** + * Creates new secret key. + * + * @param algorithmChoice + * @param keySize + * @param passphrase + * @param isMasterKey + * @return A newly created PGPSecretKey + * @throws NoSuchAlgorithmException + * @throws PGPException + * @throws NoSuchProviderException + * @throws PgpGeneralMsgIdException + * @throws InvalidAlgorithmParameterException + */ + + // TODO: key flags? public PGPSecretKey createKey(int algorithmChoice, int keySize, String passphrase, boolean isMasterKey) throws NoSuchAlgorithmException, PGPException, NoSuchProviderException, - PgpGeneralException, InvalidAlgorithmParameterException { + PgpGeneralMsgIdException, InvalidAlgorithmParameterException { if (keySize < 512) { - throw new PgpGeneralException(mContext.getString(R.string.error_key_size_minimum512bit)); + throw new PgpGeneralMsgIdException(R.string.error_key_size_minimum512bit); } if (passphrase == null) { @@ -127,8 +129,7 @@ public class PgpKeyOperation { case Id.choice.algorithm.elgamal: { if (isMasterKey) { - throw new PgpGeneralException( - mContext.getString(R.string.error_master_key_must_not_be_el_gamal)); + throw new PgpGeneralMsgIdException(R.string.error_master_key_must_not_be_el_gamal); } keyGen = KeyPairGenerator.getInstance("ElGamal", Constants.BOUNCY_CASTLE_PROVIDER_NAME); BigInteger p = Primes.getBestPrime(keySize); @@ -150,8 +151,7 @@ public class PgpKeyOperation { } default: { - throw new PgpGeneralException( - mContext.getString(R.string.error_unknown_algorithm_choice)); + throw new PgpGeneralMsgIdException(R.string.error_unknown_algorithm_choice); } } @@ -171,8 +171,9 @@ public class PgpKeyOperation { sha1Calc, isMasterKey, keyEncryptor); } - public void changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassPhrase, - String newPassPhrase) throws IOException, PGPException { + public PGPSecretKeyRing changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassPhrase, + String newPassPhrase) throws IOException, PGPException, + NoSuchProviderException { updateProgress(R.string.progress_building_key, 0, 100); if (oldPassPhrase == null) { @@ -190,16 +191,16 @@ public class PgpKeyOperation { new JcePBESecretKeyEncryptorBuilder(keyRing.getSecretKey() .getKeyEncryptionAlgorithm()).build(newPassPhrase.toCharArray())); - updateProgress(R.string.progress_saving_key_ring, 50, 100); - - ProviderHelper.saveKeyRing(mContext, newKeyRing); - - updateProgress(R.string.progress_done, 100, 100); + return newKeyRing; } - private void buildNewSecretKey(ArrayList userIds, ArrayList keys, ArrayList keysExpiryDates, ArrayList keysUsages, String newPassPhrase, String oldPassPhrase) throws PgpGeneralException, - PGPException, SignatureException, IOException { + private Pair buildNewSecretKey( + ArrayList userIds, ArrayList keys, + ArrayList keysExpiryDates, + ArrayList keysUsages, + String newPassPhrase, String oldPassPhrase) + throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException { int usageId = keysUsages.get(0); boolean canSign; @@ -210,8 +211,6 @@ public class PgpKeyOperation { // this removes all userIds and certifications previously attached to the masterPublicKey PGPPublicKey masterPublicKey = masterKey.getPublicKey(); - PGPSecretKeyRing mKR = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, masterKey.getKeyID()); - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassPhrase.toCharArray()); PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor); @@ -249,7 +248,7 @@ public class PgpKeyOperation { //here we purposefully ignore partial days in each date - long type has no fractional part! long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); if (numDays <= 0) - throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation)); + throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation); hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); } else { hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, @@ -319,9 +318,11 @@ public class PgpKeyOperation { GregorianCalendar expiryDate = keysExpiryDates.get(i); //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c //here we purposefully ignore partial days in each date - long type has no fractional part! - long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); - if (numDays <= 0) - throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation)); + long numDays = + (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); + if (numDays <= 0) { + throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation); + } hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); } else { hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, @@ -334,23 +335,18 @@ public class PgpKeyOperation { PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing(); PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing(); - updateProgress(R.string.progress_saving_key_ring, 90, 100); - - ProviderHelper.saveKeyRing(mContext, secretKeyRing); - ProviderHelper.saveKeyRing(mContext, publicKeyRing); + return new Pair(secretKeyRing, publicKeyRing); - updateProgress(R.string.progress_done, 100, 100); } - public void buildSecretKey (SaveKeyringParcel saveParcel)throws PgpGeneralException, - PGPException, SignatureException, IOException { + public Pair buildSecretKey (PGPSecretKeyRing mKR, + PGPPublicKeyRing pKR, + SaveKeyringParcel saveParcel) + throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException { updateProgress(R.string.progress_building_key, 0, 100); PGPSecretKey masterKey = saveParcel.keys.get(0); - PGPSecretKeyRing mKR = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, masterKey.getKeyID()); - PGPPublicKeyRing pKR = ProviderHelper.getPGPPublicKeyRingByKeyId(mContext, masterKey.getKeyID()); - if (saveParcel.oldPassPhrase == null) { saveParcel.oldPassPhrase = ""; } @@ -359,9 +355,8 @@ public class PgpKeyOperation { } if (mKR == null) { - buildNewSecretKey(saveParcel.userIDs, saveParcel.keys, saveParcel.keysExpiryDates, + return buildNewSecretKey(saveParcel.userIDs, saveParcel.keys, saveParcel.keysExpiryDates, saveParcel.keysUsages, saveParcel.newPassPhrase, saveParcel.oldPassPhrase); //new Keyring - return; } /* @@ -430,7 +425,7 @@ public class PgpKeyOperation { //here we purposefully ignore partial days in each date - long type has no fractional part! long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); if (numDays <= 0) - throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation)); + throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation); hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); } else { hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, @@ -592,7 +587,7 @@ public class PgpKeyOperation { //here we purposefully ignore partial days in each date - long type has no fractional part! long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); if (numDays <= 0) - throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation)); + throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation); hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); } else { hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, @@ -637,7 +632,6 @@ public class PgpKeyOperation { //update the passphrase mKR = PGPSecretKeyRing.copyWithNewPassword(mKR, keyDecryptor, keyEncryptorNew); - updateProgress(R.string.progress_saving_key_ring, 90, 100); /* additional handy debug info @@ -660,62 +654,72 @@ public class PgpKeyOperation { */ + return new Pair(mKR, pKR); - ProviderHelper.saveKeyRing(mContext, mKR); - ProviderHelper.saveKeyRing(mContext, pKR); - - updateProgress(R.string.progress_done, 100, 100); } - public PGPPublicKeyRing certifyKey(long masterKeyId, long pubKeyId, List userIds, String passphrase) - throws PgpGeneralException, NoSuchAlgorithmException, NoSuchProviderException, + /** + * Certify the given pubkeyid with the given masterkeyid. + * + * @param certificationKey Certifying key + * @param publicKey public key to certify + * @param userIds User IDs to certify, must not be null or empty + * @param passphrase Passphrase of the secret key + * @return A keyring with added certifications + */ + public PGPPublicKey certifyKey(PGPSecretKey certificationKey, PGPPublicKey publicKey, List userIds, String passphrase) + throws PgpGeneralMsgIdException, NoSuchAlgorithmException, NoSuchProviderException, PGPException, SignatureException { - if (passphrase == null) { - throw new PgpGeneralException("Unable to obtain passphrase"); - } else { - // create a signatureGenerator from the supplied masterKeyId and passphrase - PGPSignatureGenerator signatureGenerator; { + // create a signatureGenerator from the supplied masterKeyId and passphrase + PGPSignatureGenerator signatureGenerator; { - PGPSecretKey certificationKey = PgpKeyHelper.getCertificationKey(mContext, masterKeyId); - if (certificationKey == null) { - throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); - } + if (certificationKey == null) { + throw new PgpGeneralMsgIdException(R.string.error_signature_failed); + } - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray()); - PGPPrivateKey signaturePrivateKey = certificationKey.extractPrivateKey(keyDecryptor); - if (signaturePrivateKey == null) { - throw new PgpGeneralException( - mContext.getString(R.string.error_could_not_extract_private_key)); - } + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray()); + PGPPrivateKey signaturePrivateKey = certificationKey.extractPrivateKey(keyDecryptor); + if (signaturePrivateKey == null) { + throw new PgpGeneralMsgIdException(R.string.error_could_not_extract_private_key); + } - // TODO: SHA256 fixed? - JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder( - certificationKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + // TODO: SHA256 fixed? + JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder( + certificationKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); - signatureGenerator.init(PGPSignature.DEFAULT_CERTIFICATION, signaturePrivateKey); - } + signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); + signatureGenerator.init(PGPSignature.DEFAULT_CERTIFICATION, signaturePrivateKey); + } - { // supply signatureGenerator with a SubpacketVector - PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); - PGPSignatureSubpacketVector packetVector = spGen.generate(); - signatureGenerator.setHashedSubpackets(packetVector); - } + { // supply signatureGenerator with a SubpacketVector + PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); + PGPSignatureSubpacketVector packetVector = spGen.generate(); + signatureGenerator.setHashedSubpackets(packetVector); + } - // fetch public key ring, add the certification and return it - PGPPublicKeyRing pubring = ProviderHelper - .getPGPPublicKeyRingByKeyId(mContext, pubKeyId); - PGPPublicKey signedKey = pubring.getPublicKey(pubKeyId); - for(String userId : new IterableIterator(userIds.iterator())) { - PGPSignature sig = signatureGenerator.generateCertification(userId, signedKey); - signedKey = PGPPublicKey.addCertification(signedKey, userId, sig); - } - pubring = PGPPublicKeyRing.insertPublicKey(pubring, signedKey); + // fetch public key ring, add the certification and return it + for(String userId : new IterableIterator(userIds.iterator())) { + PGPSignature sig = signatureGenerator.generateCertification(userId, publicKey); + publicKey = PGPPublicKey.addCertification(publicKey, userId, sig); + } + + return publicKey; + } - return pubring; + /** Simple static subclass that stores two values. + * + * This is only used to return a pair of values in one function above. We specifically don't use + * com.android.Pair to keep this class free from android dependencies. + */ + public static class Pair { + public final K first; + public final V second; + public Pair(K first, V second) { + this.first = first; + this.second = second; } } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralException.java index bb80d27ee..418445367 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralException.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralException.java @@ -23,4 +23,7 @@ public class PgpGeneralException extends Exception { public PgpGeneralException(String message) { super(message); } + public PgpGeneralException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java new file mode 100644 index 000000000..3df85cfc8 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012-2013 Dominik Schürmann + * Copyright (C) 2010 Thialfihar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sufficientlysecure.keychain.pgp.exception; + +import android.content.Context; + +public class PgpGeneralMsgIdException extends Exception { + static final long serialVersionUID = 0xf812773343L; + + private final int msgId; + + public PgpGeneralMsgIdException(int msgId) { + super("msg[" + msgId + "]"); + this.msgId = msgId; + } + + public PgpGeneralException getContextualized(Context context) { + return new PgpGeneralException(context.getString(msgId), this); + } +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 2060c6f61..f82e5e619 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -35,6 +35,8 @@ import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.pgp.*; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; +import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; import org.sufficientlysecure.keychain.util.*; @@ -473,14 +475,26 @@ public class KeychainIntentService extends IntentService long masterKeyId = saveParams.keys.get(0).getKeyID(); - PgpKeyOperation keyOperations = new PgpKeyOperation(this, this); /* Operation */ if (!canSign) { - keyOperations.changeSecretKeyPassphrase( - ProviderHelper.getPGPSecretKeyRingByKeyId(this, masterKeyId), + PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 50, 100)); + PGPSecretKeyRing keyRing = ProviderHelper + .getPGPSecretKeyRingByKeyId(this, masterKeyId); + keyRing = keyOperations.changeSecretKeyPassphrase(keyRing, oldPassPhrase, newPassPhrase); + setProgress(R.string.progress_saving_key_ring, 50, 100); + ProviderHelper.saveKeyRing(this, keyRing); + setProgress(R.string.progress_done, 100, 100); } else { - keyOperations.buildSecretKey(saveParams); + PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 90, 100)); + PGPSecretKeyRing privkey = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, masterKeyId); + PGPPublicKeyRing pubkey = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, masterKeyId); + PgpKeyOperation.Pair pair = + keyOperations.buildSecretKey(privkey, pubkey, saveParams); + setProgress(R.string.progress_saving_key_ring, 90, 100); + ProviderHelper.saveKeyRing(this, pair.first); + ProviderHelper.saveKeyRing(this, pair.second); + setProgress(R.string.progress_done, 100, 100); } PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassPhrase); @@ -498,7 +512,7 @@ public class KeychainIntentService extends IntentService boolean masterKey = data.getBoolean(GENERATE_KEY_MASTER_KEY); /* Operation */ - PgpKeyOperation keyOperations = new PgpKeyOperation(this, this); + PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 100, 100)); PGPSecretKey newKey = keyOperations.createKey(algorithm, keysize, passphrase, masterKey); @@ -529,7 +543,7 @@ public class KeychainIntentService extends IntentService getQuantityString(R.plurals.progress_generating, keysTotal), keysCreated, keysTotal); - PgpKeyOperation keyOperations = new PgpKeyOperation(this, this); + PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 100, 100)); PGPSecretKey masterKey = keyOperations.createKey(Id.choice.algorithm.rsa, 4096, passphrase, true); @@ -771,14 +785,23 @@ public class KeychainIntentService extends IntentService /* Operation */ String signaturePassPhrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId); + if (signaturePassPhrase == null) { + throw new PgpGeneralException("Unable to obtain passphrase"); + } - PgpKeyOperation keyOperation = new PgpKeyOperation(this, this); - PGPPublicKeyRing signedPubKeyRing = keyOperation.certifyKey(masterKeyId, pubKeyId, + PgpKeyOperation keyOperation = new PgpKeyOperation(new ProgressScaler(this, 0, 100, 100)); + PGPPublicKeyRing publicRing = ProviderHelper + .getPGPPublicKeyRingByKeyId(this, pubKeyId); + PGPPublicKey publicKey = publicRing.getPublicKey(pubKeyId); + PGPSecretKey certificationKey = PgpKeyHelper.getCertificationKey(this, + masterKeyId); + publicKey = keyOperation.certifyKey(certificationKey, publicKey, userIds, signaturePassPhrase); + publicRing = PGPPublicKeyRing.insertPublicKey(publicRing, publicKey); // store the signed key in our local cache PgpImportExport pgpImportExport = new PgpImportExport(this, null); - int retval = pgpImportExport.storeKeyRingInCache(signedPubKeyRing); + int retval = pgpImportExport.storeKeyRingInCache(publicRing); if (retval != Id.return_value.ok && retval != Id.return_value.updated) { throw new PgpGeneralException("Failed to store signed key in local cache"); } @@ -795,7 +818,11 @@ public class KeychainIntentService extends IntentService if (this.mIsCanceled) { return; } - Log.e(Constants.TAG, "KeychainIntentService Exception: ", e); + // contextualize the exception, if necessary + if(e instanceof PgpGeneralMsgIdException) { + e = ((PgpGeneralMsgIdException) e).getContextualized(this); + } + Log.e(Constants.TAG, "ApgService Exception: ", e); e.printStackTrace(); Bundle data = new Bundle(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java new file mode 100644 index 000000000..15b70e22e --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +package org.sufficientlysecure.keychain.util; + +/** This is a simple class that wraps a ProgressDialogUpdater, scaling the progress + * values into a specified range. + */ +public class ProgressScaler implements ProgressDialogUpdater { + + final ProgressDialogUpdater mWrapped; + final int mFrom, mTo, mMax; + + public ProgressScaler(ProgressDialogUpdater wrapped, int from, int to, int max) { + this.mWrapped = wrapped; + this.mFrom = from; + this.mTo = to; + this.mMax = max; + } + + /** + * Set progressDialogUpdater of ProgressDialog by sending message to handler on UI thread + */ + public void setProgress(String message, int progress, int max) { + mWrapped.setProgress(message, mFrom+ progress*(mTo-mFrom)/max, mMax); + } + + public void setProgress(int resourceId, int progress, int max) { + mWrapped.setProgress(resourceId, progress, mMax); + } + + public void setProgress(int progress, int max) { + mWrapped.setProgress(progress, max); + } + +} -- cgit v1.2.3 From 7000ab37fda358b93ec89dd77b5b2b42c5ec6420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 16:15:50 +0200 Subject: default to allow symmetric decryption --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 741c1323a..29255fbbe 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -101,7 +101,7 @@ public class PgpDecryptVerify { // optional private ProgressDialogUpdater mProgressDialogUpdater = null; - private boolean mAllowSymmetricDecryption = false; + private boolean mAllowSymmetricDecryption = true; private String mPassphrase = null; private long mEnforcedKeyId = 0; -- cgit v1.2.3 From acc2e208cf0ac4ecd5daaddfe844b37fa8057432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 16:18:16 +0200 Subject: Remove DECRYPT_ASSUME_SYMMETRIC --- .../java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java | 3 --- .../org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java | 3 --- 2 files changed, 6 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index cec6d7a59..8a89ad240 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -182,9 +182,6 @@ public class DecryptFileFragment extends DecryptFragment { data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, passphrase); - // TODO - data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, false); - intent.putExtra(KeychainIntentService.EXTRA_DATA, data); // Message is received after encrypting is done in KeychainIntentService diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java index 197a2af04..d7a22038d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java @@ -129,9 +129,6 @@ public class DecryptMessageFragment extends DecryptFragment { data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, message.getBytes()); data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, passphrase); - // TODO - data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, false); - intent.putExtra(KeychainIntentService.EXTRA_DATA, data); // Message is received after encrypting is done in KeychainIntentService -- cgit v1.2.3 From ddfb7e10e866379bf56ea9ad983fb2ca32c1dee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 16:39:18 +0200 Subject: Fully qualified imports --- .../sufficientlysecure/keychain/pgp/PgpHelper.java | 8 +++++- .../keychain/pgp/PgpImportExport.java | 15 ++++++++--- .../keychain/pgp/PgpKeyHelper.java | 13 ++++++++-- .../keychain/pgp/PgpKeyOperation.java | 29 +++++++++++++++++++--- .../keychain/pgp/PgpSignEncrypt.java | 26 ++++++++++++++++--- .../sufficientlysecure/keychain/pgp/PgpToX509.java | 24 +++++++++++++----- .../keychain/ui/DecryptFileFragment.java | 3 +++ 7 files changed, 99 insertions(+), 19 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java index cc40afbac..7a3338c7c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java @@ -21,7 +21,13 @@ import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; -import org.spongycastle.openpgp.*; +import org.spongycastle.openpgp.PGPEncryptedDataList; +import org.spongycastle.openpgp.PGPObjectFactory; +import org.spongycastle.openpgp.PGPPublicKeyEncryptedData; +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.spongycastle.openpgp.PGPUtil; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index 0e0fdec83..de405d132 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -20,8 +20,14 @@ package org.sufficientlysecure.keychain.pgp; import android.content.Context; import android.os.Bundle; import android.os.Environment; + import org.spongycastle.bcpg.ArmoredOutputStream; -import org.spongycastle.openpgp.*; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPKeyRing; +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; @@ -30,13 +36,16 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; -import org.sufficientlysecure.keychain.util.*; +import org.sufficientlysecure.keychain.util.HkpKeyServer; +import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException; +import org.sufficientlysecure.keychain.util.KeychainServiceListener; +import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.security.Provider; import java.util.ArrayList; import java.util.List; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index b4bf0747f..89352ef31 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -24,7 +24,12 @@ import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; import org.spongycastle.bcpg.sig.KeyFlags; -import org.spongycastle.openpgp.*; +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.spongycastle.openpgp.PGPSignature; +import org.spongycastle.openpgp.PGPSignatureSubpacketVector; import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -35,7 +40,11 @@ import org.sufficientlysecure.keychain.util.Log; import java.security.DigestException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.*; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 520189448..0e828d859 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -22,25 +22,46 @@ import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.spec.ElGamalParameterSpec; -import org.spongycastle.openpgp.*; +import org.spongycastle.openpgp.PGPEncryptedData; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPKeyPair; +import org.spongycastle.openpgp.PGPKeyRingGenerator; +import org.spongycastle.openpgp.PGPPrivateKey; +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.spongycastle.openpgp.PGPSignature; +import org.spongycastle.openpgp.PGPSignatureGenerator; +import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.spongycastle.openpgp.PGPSignatureSubpacketVector; import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor; import org.spongycastle.openpgp.operator.PGPContentSignerBuilder; import org.spongycastle.openpgp.operator.PGPDigestCalculator; -import org.spongycastle.openpgp.operator.jcajce.*; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair; +import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Primes; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; -import org.sufficientlysecure.keychain.util.IterableIterator; import java.io.IOException; import java.math.BigInteger; -import java.security.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.SignatureException; import java.util.ArrayList; import java.util.Date; import java.util.GregorianCalendar; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java index 6d80c154b..f4fa95fca 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -21,9 +21,25 @@ import android.content.Context; import org.spongycastle.bcpg.ArmoredOutputStream; import org.spongycastle.bcpg.BCPGOutputStream; -import org.spongycastle.openpgp.*; +import org.spongycastle.openpgp.PGPCompressedDataGenerator; +import org.spongycastle.openpgp.PGPEncryptedDataGenerator; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPLiteralData; +import org.spongycastle.openpgp.PGPLiteralDataGenerator; +import org.spongycastle.openpgp.PGPPrivateKey; +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.spongycastle.openpgp.PGPSignature; +import org.spongycastle.openpgp.PGPSignatureGenerator; +import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.spongycastle.openpgp.PGPV3SignatureGenerator; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; -import org.spongycastle.openpgp.operator.jcajce.*; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; +import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; @@ -33,7 +49,11 @@ import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; -import java.io.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SignatureException; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java index 54601173d..fa54afa86 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java @@ -18,7 +18,13 @@ package org.sufficientlysecure.keychain.pgp; import org.spongycastle.asn1.DERObjectIdentifier; -import org.spongycastle.asn1.x509.*; +import org.spongycastle.asn1.x509.AuthorityKeyIdentifier; +import org.spongycastle.asn1.x509.BasicConstraints; +import org.spongycastle.asn1.x509.GeneralName; +import org.spongycastle.asn1.x509.GeneralNames; +import org.spongycastle.asn1.x509.SubjectKeyIdentifier; +import org.spongycastle.asn1.x509.X509Extensions; +import org.spongycastle.asn1.x509.X509Name; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPPublicKey; @@ -29,13 +35,14 @@ import org.spongycastle.x509.extension.SubjectKeyIdentifierStructure; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.util.Log; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; import java.io.IOException; import java.math.BigInteger; -import java.security.*; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SignatureException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.text.DateFormat; @@ -43,6 +50,11 @@ import java.util.Date; import java.util.Iterator; import java.util.Vector; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; + public class PgpToX509 { public static final String DN_COMMON_PART_O = "OpenPGP to X.509 Bridge"; public static final String DN_COMMON_PART_OU = "OpenPGP Keychain cert"; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index 8a89ad240..ed6366353 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -203,6 +203,9 @@ public class DecryptFileFragment extends DecryptFragment { } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { showPassphraseDialog(Id.key.symmetric); } else { + AppMsg.makeText(getActivity(), R.string.decryption_successful, + AppMsg.STYLE_INFO).show(); + if (mDeleteAfter.isChecked()) { // Create and show dialog to delete original file DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment -- cgit v1.2.3 From ecca54d4d5df452fccbdd092a4671ef04cad8157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 17:08:56 +0200 Subject: Automatically select newly created key in api accounts --- .../remote/ui/AccountSettingsFragment.java | 29 ++++++++++++++++++++-- .../keychain/service/KeychainIntentService.java | 1 + .../keychain/ui/EditKeyActivity.java | 8 ++++++ .../keychain/ui/SelectSecretKeyLayoutFragment.java | 27 ++++++++------------ 4 files changed, 47 insertions(+), 18 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java index 0931e6e31..eec54b4cc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java @@ -17,7 +17,9 @@ package org.sufficientlysecure.keychain.remote.ui; +import android.app.Activity; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; @@ -31,6 +33,7 @@ import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.remote.AccountSettings; import org.sufficientlysecure.keychain.ui.EditKeyActivity; import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; @@ -40,6 +43,8 @@ import org.sufficientlysecure.keychain.util.AlgorithmNames; public class AccountSettingsFragment extends Fragment implements SelectSecretKeyLayoutFragment.SelectSecretKeyCallback { + private static final int REQUEST_CODE_CREATE_KEY = 0x00008884; + // model private AccountSettings mAccSettings; @@ -64,7 +69,8 @@ public class AccountSettingsFragment extends Fragment implements this.mAccSettings = accountSettings; mAccNameView.setText(accountSettings.getAccountName()); - mSelectKeyFragment.selectKey(accountSettings.getKeyId()); + Uri keyUri = KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(accountSettings.getKeyId())); + mSelectKeyFragment.selectKey(keyUri); mEncryptionAlgorithm.setSelection(mEncryptionAdapter.getPosition(accountSettings .getEncryptionAlgorithm())); mHashAlgorithm.setSelection(mHashAdapter.getPosition(accountSettings.getHashAlgorithm())); @@ -162,7 +168,26 @@ public class AccountSettingsFragment extends Fragment implements intent.putExtra(EditKeyActivity.EXTRA_GENERATE_DEFAULT_KEYS, true); // set default user id to account name TODO: not working currently in EditKey intent.putExtra(EditKeyActivity.EXTRA_USER_IDS, mAccSettings.getAccountName()); - startActivityForResult(intent, 0); + startActivityForResult(intent, REQUEST_CODE_CREATE_KEY); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case REQUEST_CODE_CREATE_KEY: { + if (resultCode == Activity.RESULT_OK) { + // select newly created key + Uri newKeyUri = data.getData(); + mSelectKeyFragment.selectKey(newKeyUri); + } + break; + } + + default: + super.onActivityResult(requestCode, resultCode, data); + + break; + } } /** diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index f82e5e619..110f06634 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.pgp.*; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 9df84065f..a17cfaafc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -621,7 +621,15 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { Intent data = new Intent(); + + // TODO: remove, now using uri! data.putExtra(RESULT_EXTRA_MASTER_KEY_ID, getMasterKeyId()); + + // return uri pointing to new created key + Uri uri = KeychainContract.KeyRings.buildPublicKeyRingsByKeyIdUri( + String.valueOf(getMasterKeyId())); + data.setData(uri); + ArrayList userIds = null; try { userIds = getUserIds(mUserIdsView); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java index cbc0f4c5c..d0abe0f6f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java @@ -40,6 +40,8 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderManager.LoaderCallbacks { + private static final int REQUEST_CODE_SELECT_KEY = 0x00008882; + private TextView mKeyUserId; private TextView mKeyUserIdRest; private TextView mKeyMasterKeyIdHex; @@ -51,14 +53,10 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan private SelectSecretKeyCallback mCallback; - private static final int REQUEST_CODE_SELECT_KEY = 8882; - - private static final int LOADER_ID = 0; - - //The Projection we will retrieve, Master Key ID is for convenience sake, - //to avoid having to pass the Key Around - final String[] PROJECTION = new String[]{KeychainContract.UserIds.USER_ID - , KeychainContract.KeyRings.MASTER_KEY_ID}; + final String[] PROJECTION = new String[]{ + KeychainContract.UserIds.USER_ID, + KeychainContract.KeyRings.MASTER_KEY_ID + }; final int INDEX_USER_ID = 0; final int INDEX_MASTER_KEY_ID = 1; @@ -82,7 +80,6 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan } public void setSelectedKeyData(String userName, String email, String masterKeyHex) { - mNoKeySelected.setVisibility(View.GONE); mKeyUserId.setText(userName); @@ -124,11 +121,9 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan return view; } - //For AppSettingsFragment - public void selectKey(long masterKeyId) { - Uri buildUri = KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(masterKeyId)); - mReceivedUri = buildUri; - getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this); + public void selectKey(Uri keyUri) { + mReceivedUri = keyUri; + getActivity().getSupportLoaderManager().restartLoader(0, null, this); } private void startSelectKeyActivity() { @@ -188,13 +183,13 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan // Secret Key Fragment.Intent contains the passed Uri @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode & 0xFFFF) { + switch (requestCode) { case REQUEST_CODE_SELECT_KEY: { if (resultCode == Activity.RESULT_OK) { mReceivedUri = data.getData(); //Must be restartLoader() or the data will not be updated on selecting a new key - getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this); + getActivity().getSupportLoaderManager().restartLoader(0, null, this); mKeyUserId.setError(null); -- cgit v1.2.3 From 2f9cb69a1e10bff580abb909614662fd6de69255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 17:13:53 +0200 Subject: Cleanup --- .../keychain/ui/EditKeyActivity.java | 129 +++++++++------------ .../keychain/ui/SelectSecretKeyLayoutFragment.java | 5 - 2 files changed, 55 insertions(+), 79 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index a17cfaafc..2cdd64f4a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Dominik Schürmann + * Copyright (C) 2012-2014 Dominik Schürmann * Copyright (C) 2010 Thialfihar * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,13 +17,8 @@ package org.sufficientlysecure.keychain.ui; -import java.util.ArrayList; -import java.util.GregorianCalendar; -import java.util.List; -import java.util.Vector; - -import org.spongycastle.bcpg.sig.KeyFlags; import android.app.Activity; +import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; @@ -33,14 +28,20 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Messenger; +import android.support.v4.app.ActivityCompat; import android.support.v7.app.ActionBarActivity; -import android.view.*; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; import android.view.View.OnClickListener; +import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.LinearLayout; import android.widget.Toast; + import com.beardedhen.androidbootstrap.BootstrapButton; import com.devspark.appmsg.AppMsg; @@ -63,20 +64,17 @@ import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.widget.Editor; +import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener; import org.sufficientlysecure.keychain.ui.widget.KeyEditor; import org.sufficientlysecure.keychain.ui.widget.SectionView; import org.sufficientlysecure.keychain.ui.widget.UserIdEditor; -import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; -import android.app.AlertDialog; -import android.support.v4.app.ActivityCompat; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; +import java.util.ArrayList; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.Vector; public class EditKeyActivity extends ActionBarActivity implements EditorListener { @@ -89,10 +87,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public static final String EXTRA_NO_PASSPHRASE = "no_passphrase"; public static final String EXTRA_GENERATE_DEFAULT_KEYS = "generate_default_keys"; - // results when saving key - public static final String RESULT_EXTRA_MASTER_KEY_ID = "master_key_id"; - public static final String RESULT_EXTRA_USER_ID = "user_id"; - // EDIT private Uri mDataUri; @@ -119,8 +113,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener ExportHelper mExportHelper; - public boolean needsSaving() - { + public boolean needsSaving() { mNeedsSaving = (mUserIdsView == null) ? false : mUserIdsView.needsSaving(); mNeedsSaving |= (mKeysView == null) ? false : mKeysView.needsSaving(); mNeedsSaving |= hasPassphraseChanged(); @@ -129,19 +122,16 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } - public void somethingChanged() - { + public void somethingChanged() { ActivityCompat.invalidateOptionsMenu(this); //Toast.makeText(this, "Needs saving: " + Boolean.toString(mNeedsSaving) + "(" + Boolean.toString(mUserIdsView.needsSaving()) + ", " + Boolean.toString(mKeysView.needsSaving()) + ")", Toast.LENGTH_LONG).show(); } - public void onDeleted(Editor e, boolean wasNewItem) - { + public void onDeleted(Editor e, boolean wasNewItem) { somethingChanged(); } - public void onEdited() - { + public void onEdited() { somethingChanged(); } @@ -337,41 +327,42 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - case android.R.id.home: - cancelClicked(); //TODO: why isn't this triggered on my tablet - one of many ui problems I've had with this device. A code compatibility issue or a Samsung fail? - return true; - case R.id.menu_key_edit_cancel: - cancelClicked(); - return true; - case R.id.menu_key_edit_export_file: - if (needsSaving()) { - Toast.makeText(this, R.string.error_save_first, Toast.LENGTH_LONG).show(); - } else { - long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri); - long[] ids = new long[]{masterKeyId}; - mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC, - null); + case android.R.id.home: + cancelClicked(); //TODO: why isn't this triggered on my tablet - one of many ui problems I've had with this device. A code compatibility issue or a Samsung fail? return true; - } - return true; - case R.id.menu_key_edit_delete: - long rowId= ProviderHelper.getRowId(this,mDataUri); - Uri convertUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)); - // Message is received after key is deleted - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) { - setResult(RESULT_CANCELED); - finish(); + case R.id.menu_key_edit_cancel: + cancelClicked(); + return true; + case R.id.menu_key_edit_export_file: + if (needsSaving()) { + Toast.makeText(this, R.string.error_save_first, Toast.LENGTH_LONG).show(); + } else { + long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri); + long[] ids = new long[]{masterKeyId}; + mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC, + null); + return true; + } + return true; + case R.id.menu_key_edit_delete: + long rowId = ProviderHelper.getRowId(this, mDataUri); + Uri convertUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)); + // Message is received after key is deleted + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) { + setResult(RESULT_CANCELED); + finish(); + } } - }}; - mExportHelper.deleteKey(convertUri, returnHandler); - return true; + }; + mExportHelper.deleteKey(convertUri, returnHandler); + return true; - case R.id.menu_key_edit_save: - saveClicked(); - return true; + case R.id.menu_key_edit_save: + saveClicked(); + return true; } return super.onOptionsItemSelected(item); } @@ -458,6 +449,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener /** * Build layout based on mUserId, mKeys and mKeysUsages Vectors. It creates Views for every user * id and key. + * * @param newKeys */ private void buildLayout(boolean newKeys) { @@ -471,7 +463,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout container = (LinearLayout) findViewById(R.id.edit_key_container); - if(mIsPassPhraseSet){ + if (mIsPassPhraseSet) { mChangePassphrase.setText(getString(R.string.btn_change_passphrase)); } mUserIdsView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); @@ -532,15 +524,14 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } } - public boolean hasPassphraseChanged() - { + public boolean hasPassphraseChanged() { if (mNoPassphrase != null) { if (mNoPassphrase.isChecked()) { return mIsPassPhraseSet; } else { return (mNewPassPhrase != null && !mNewPassPhrase.equals("")); } - }else { + } else { return false; } } @@ -622,21 +613,11 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { Intent data = new Intent(); - // TODO: remove, now using uri! - data.putExtra(RESULT_EXTRA_MASTER_KEY_ID, getMasterKeyId()); - // return uri pointing to new created key Uri uri = KeychainContract.KeyRings.buildPublicKeyRingsByKeyIdUri( String.valueOf(getMasterKeyId())); data.setData(uri); - ArrayList userIds = null; - try { - userIds = getUserIds(mUserIdsView); - } catch (PgpGeneralException e) { - Log.e(Constants.TAG, "exception while getting user ids", e); - } - data.putExtra(RESULT_EXTRA_USER_ID, userIds.get(0)); setResult(RESULT_OK, data); finish(); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java index d0abe0f6f..d1ba431d6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java @@ -89,7 +89,6 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan mKeyUserId.setVisibility(View.VISIBLE); mKeyUserIdRest.setVisibility(View.VISIBLE); mKeyMasterKeyIdHex.setVisibility(View.VISIBLE); - } public void setError(String error) { @@ -134,7 +133,6 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan @Override public Loader onCreateLoader(int id, Bundle args) { - //We don't care about the Loader id return new CursorLoader(getActivity(), mReceivedUri, PROJECTION, null, null, null); } @@ -179,8 +177,6 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan return; } - // Select Secret Key Activity delivers the intent which was sent by it using interface to Select - // Secret Key Fragment.Intent contains the passed Uri @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { @@ -192,7 +188,6 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan getActivity().getSupportLoaderManager().restartLoader(0, null, this); mKeyUserId.setError(null); - } break; } -- cgit v1.2.3 From d0947e8377283f8780b5e7555dd321950a2de147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 18:44:36 +0200 Subject: Only allow private keys associated to accounts of an app --- .../keychain/pgp/PgpDecryptVerify.java | 23 +++++++++++----------- .../keychain/provider/ProviderHelper.java | 20 +++++++++++++++++-- .../keychain/remote/OpenPgpService.java | 12 +++++++---- .../keychain/remote/RemoteService.java | 2 +- 4 files changed, 39 insertions(+), 18 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 29255fbbe..003db632d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -67,6 +67,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.security.SignatureException; import java.util.Iterator; +import java.util.Set; /** * This class uses a Builder pattern! @@ -79,7 +80,7 @@ public class PgpDecryptVerify { private ProgressDialogUpdater mProgressDialogUpdater; private boolean mAllowSymmetricDecryption; private String mPassphrase; - private long mEnforcedKeyId; + private Set mAllowedKeyIds; private PgpDecryptVerify(Builder builder) { // private Constructor can only be called from Builder @@ -90,7 +91,7 @@ public class PgpDecryptVerify { this.mProgressDialogUpdater = builder.mProgressDialogUpdater; this.mAllowSymmetricDecryption = builder.mAllowSymmetricDecryption; this.mPassphrase = builder.mPassphrase; - this.mEnforcedKeyId = builder.mEnforcedKeyId; + this.mAllowedKeyIds = builder.mAllowedKeyIds; } public static class Builder { @@ -103,7 +104,7 @@ public class PgpDecryptVerify { private ProgressDialogUpdater mProgressDialogUpdater = null; private boolean mAllowSymmetricDecryption = true; private String mPassphrase = null; - private long mEnforcedKeyId = 0; + private Set mAllowedKeyIds = null; public Builder(Context context, InputData data, OutputStream outStream) { this.mContext = context; @@ -127,14 +128,14 @@ public class PgpDecryptVerify { } /** - * Allow this key id alone for decryption. - * This means only ciphertexts encrypted for this private key can be decrypted. + * Allow these key ids alone for decryption. + * This means only ciphertexts encrypted for one of these private key can be decrypted. * - * @param enforcedKeyId + * @param allowedKeyIds * @return */ - public Builder enforcedKeyId(long enforcedKeyId) { - this.mEnforcedKeyId = enforcedKeyId; + public Builder allowedKeyIds(Set allowedKeyIds) { + this.mAllowedKeyIds = allowedKeyIds; return this; } @@ -236,16 +237,16 @@ public class PgpDecryptVerify { // secret key exists in database // allow only a specific key for decryption? - if (mEnforcedKeyId != 0) { + if (mAllowedKeyIds != null) { // TODO: improve this code! get master key directly! PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, encData.getKeyID()); long masterKeyId = PgpKeyHelper.getMasterKey(secretKeyRing).getKeyID(); Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID()); - Log.d(Constants.TAG, "enforcedKeyId: " + mEnforcedKeyId); + Log.d(Constants.TAG, "allowedKeyIds: " + mAllowedKeyIds); Log.d(Constants.TAG, "masterKeyId: " + masterKeyId); - if (mEnforcedKeyId != masterKeyId) { + if (!mAllowedKeyIds.contains(masterKeyId)) { throw new PgpGeneralException( mContext.getString(R.string.error_no_secret_key_found)); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index b971143ae..13dc2af2b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -48,6 +48,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Date; +import java.util.HashSet; +import java.util.Set; public class ProviderHelper { @@ -867,10 +869,10 @@ public class ProviderHelper { return settings; } - public static AccountSettings getApiAccountSettings(Context context, Uri uri) { + public static AccountSettings getApiAccountSettings(Context context, Uri accountUri) { AccountSettings settings = null; - Cursor cur = context.getContentResolver().query(uri, null, null, null, null); + Cursor cur = context.getContentResolver().query(accountUri, null, null, null, null); if (cur != null && cur.moveToFirst()) { settings = new AccountSettings(); @@ -889,6 +891,20 @@ public class ProviderHelper { return settings; } + public static Set getAllKeyIdsForApp(Context context, Uri uri) { + Set keyIds = new HashSet(); + + Cursor cursor = context.getContentResolver().query(uri, null, null, null, null); + if (cursor != null) { + int keyIdColumn = cursor.getColumnIndex(KeychainContract.ApiAccounts.KEY_ID); + while (cursor.moveToNext()) { + keyIds.add(cursor.getLong(keyIdColumn)); + } + } + + return keyIds; + } + public static byte[] getApiAppSignature(Context context, String packageName) { Uri queryUri = ApiApps.buildByPackageNameUri(packageName); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 1cd5862e7..b00c012b8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -45,6 +45,7 @@ import org.sufficientlysecure.keychain.util.Log; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Set; public class OpenPgpService extends RemoteService { @@ -276,7 +277,7 @@ public class OpenPgpService extends RemoteService { } private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input, - ParcelFileDescriptor output, AccountSettings accSettings) { + ParcelFileDescriptor output, Set allowedKeyIds) { try { // Get Input- and OutputStream from ParcelFileDescriptor InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); @@ -291,7 +292,7 @@ public class OpenPgpService extends RemoteService { PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os); builder.allowSymmetricDecryption(false) // no support for symmetric encryption - .enforcedKeyId(accSettings.getKeyId()) // allow only the private key for this app for decryption + .allowedKeyIds(allowedKeyIds) // allow only private keys associated with accounts of this app .passphrase(passphrase); // TODO: currently does not support binary signed-only content @@ -299,7 +300,7 @@ public class OpenPgpService extends RemoteService { if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId()); + Intent passphraseBundle = getPassphraseBundleIntent(data, decryptVerifyResult.getKeyIdPassphraseNeeded()); return passphraseBundle; } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { throw new PgpGeneralException("Decryption of symmetric content not supported by API!"); @@ -452,7 +453,10 @@ public class OpenPgpService extends RemoteService { } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) { return encryptAndSignImpl(data, input, output, accSettings, true); } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) { - return decryptAndVerifyImpl(data, input, output, accSettings); + String currentPkg = getCurrentCallingPackage(); + Set allowedKeyIds = + ProviderHelper.getAllKeyIdsForApp(mContext, KeychainContract.ApiAccounts.buildBaseUri(currentPkg)); + return decryptAndVerifyImpl(data, input, output, allowedKeyIds); } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) { return getKeyImpl(data); } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java index 59a04a10e..3e72eec17 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java @@ -127,7 +127,7 @@ public abstract class RemoteService extends Service { * * @return package name */ - private String getCurrentCallingPackage() { + protected String getCurrentCallingPackage() { // TODO: // callingPackages contains more than one entry when sharedUserId has been used... String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid()); -- cgit v1.2.3 From 07fdd6363f06b59aeb9206d64ed719a97a87ff99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 18:49:19 +0200 Subject: Change path to OpenKeychain --- .../main/java/org/sufficientlysecure/keychain/Constants.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index f9a7962ec..5062800db 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -47,7 +47,7 @@ public final class Constants { public static final class Path { public static final String APP_DIR = Environment.getExternalStorageDirectory() - + "/OpenPGP-Keychain"; + + "/OpenKeychain"; public static final String APP_DIR_FILE_SEC = APP_DIR + "/secexport.asc"; public static final String APP_DIR_FILE_PUB = APP_DIR + "/pubexport.asc"; } @@ -74,7 +74,12 @@ public final class Constants { public static final Class DECRYPT = DecryptActivity.class; public static final Class IMPORT_KEYS = ImportKeysActivity.class; public static final Class REGISTERED_APPS_LIST = AppsListActivity.class; - public static final Class[] ARRAY = new Class[]{KEY_LIST, ENCRYPT, DECRYPT, - IMPORT_KEYS, REGISTERED_APPS_LIST}; + public static final Class[] ARRAY = new Class[]{ + KEY_LIST, + ENCRYPT, + DECRYPT, + IMPORT_KEYS, + REGISTERED_APPS_LIST + }; } } -- cgit v1.2.3 From c414dd2fe94575deb157504fb0445df26b02feec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 19:00:14 +0200 Subject: Dont show encrypted data before decryption from clipboard --- .../keychain/ui/DecryptMessageFragment.java | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java index d7a22038d..c7a56449b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java @@ -47,10 +47,14 @@ import java.util.regex.Matcher; public class DecryptMessageFragment extends DecryptFragment { public static final String ARG_CIPHERTEXT = "ciphertext"; + // view private EditText mMessage; private BootstrapButton mDecryptButton; private BootstrapButton mDecryptFromCLipboardButton; + // model + private String mCiphertext; + /** * Inflate the layout for this fragment */ @@ -64,13 +68,13 @@ public class DecryptMessageFragment extends DecryptFragment { mDecryptButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - decryptStart(null); + decryptClicked(); } }); mDecryptFromCLipboardButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - decryptFromClipboard(); + decryptFromClipboardClicked(); } }); @@ -88,7 +92,12 @@ public class DecryptMessageFragment extends DecryptFragment { } } - private void decryptFromClipboard() { + private void decryptClicked() { + mCiphertext = mMessage.getText().toString(); + decryptStart(null); + } + + private void decryptFromClipboardClicked() { CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity()); // only decrypt if clipboard content is available and a pgp message or cleartext signature @@ -98,8 +107,7 @@ public class DecryptMessageFragment extends DecryptFragment { matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(clipboardText); } if (matcher.matches()) { - String data = matcher.group(1); - mMessage.setText(data); + mCiphertext = matcher.group(1); decryptStart(null); } else { AppMsg.makeText(getActivity(), R.string.error_invalid_data, AppMsg.STYLE_INFO) @@ -125,8 +133,7 @@ public class DecryptMessageFragment extends DecryptFragment { // data data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); - String message = mMessage.getText().toString(); - data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, message.getBytes()); + data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, mCiphertext.getBytes()); data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, passphrase); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); -- cgit v1.2.3 From d8001f9bbd83207922903f6a99872be5c2bac659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 1 Apr 2014 19:31:36 +0200 Subject: Menu cleanup --- .../java/org/sufficientlysecure/keychain/ui/KeyListActivity.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java index 06df6f12d..27d3bbbb0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java @@ -21,6 +21,7 @@ import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; @@ -55,10 +56,6 @@ public class KeyListActivity extends DrawerActivity { case R.id.menu_key_list_import: callIntentForDrawerItem(Constants.DrawerItems.IMPORT_KEYS); - return true; - case R.id.menu_key_list_export: - mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB, null); - return true; case R.id.menu_key_list_create: createKey(); @@ -67,6 +64,10 @@ public class KeyListActivity extends DrawerActivity { case R.id.menu_key_list_create_expert: createKeyExpert(); + return true; + case R.id.menu_key_list_export_public: + mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB, null); + return true; case R.id.menu_key_list_secret_export: mExportHelper.showExportKeysDialog(null, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC, null); -- cgit v1.2.3 From abfe416503517ca6eaa1569818154fb498ec1741 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Tue, 1 Apr 2014 23:02:35 +0100 Subject: sort out saving empty string IDs --- .../org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 0e828d859..0aa8b7410 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -478,9 +478,7 @@ public class PgpKeyOperation { PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); sigList.add(new Pair(userId, certification)); } - if (!origID.equals("")) { - masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID); - } + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID); userIDIndex++; } for (Pair toAdd : sigList) { @@ -502,9 +500,7 @@ public class PgpKeyOperation { sGen.setUnhashedSubpackets(unhashedPacketsGen.generate()); } PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); - if (!origID.equals("")) { - masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID); - } + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID); masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); } userIDIndex++; @@ -523,9 +519,7 @@ public class PgpKeyOperation { sigList.add(new Pair(userId, sig)); } } - if (!userId.equals("")) { - masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, userId); - } + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, userId); userIDIndex++; } anyIDChanged = true; -- cgit v1.2.3 From 2ad616ed3f8a801c34da8b10f38103afc0cfe436 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Tue, 1 Apr 2014 23:37:13 +0100 Subject: pass through info that keys are new without relying on new keys orginally being empty --- .../org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 8 ++++++-- .../sufficientlysecure/keychain/service/SaveKeyringParcel.java | 3 +++ .../org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 1 + .../org/sufficientlysecure/keychain/ui/widget/SectionView.java | 10 ++++++++++ .../sufficientlysecure/keychain/ui/widget/UserIdEditor.java | 2 ++ 5 files changed, 22 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 0aa8b7410..66f1f3f01 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -478,7 +478,9 @@ public class PgpKeyOperation { PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); sigList.add(new Pair(userId, certification)); } - masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID); + if (!saveParcel.newIDs[userIDIndex]) { + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID); + } userIDIndex++; } for (Pair toAdd : sigList) { @@ -500,7 +502,9 @@ public class PgpKeyOperation { sGen.setUnhashedSubpackets(unhashedPacketsGen.generate()); } PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); - masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID); + if (!saveParcel.newIDs[userIDIndex]) { + masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID); + } masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); } userIDIndex++; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index c99284847..b7ae4e1f1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -32,6 +32,7 @@ public class SaveKeyringParcel implements Parcelable { public ArrayList userIDs; public ArrayList originalIDs; public ArrayList deletedIDs; + public boolean[] newIDs; public boolean primaryIDChanged; public boolean[] moddedKeys; public ArrayList deletedKeys; @@ -50,6 +51,7 @@ public class SaveKeyringParcel implements Parcelable { userIDs = (ArrayList)source.readSerializable(); originalIDs = (ArrayList)source.readSerializable(); deletedIDs = (ArrayList)source.readSerializable(); + newIDs = source.createBooleanArray(); primaryIDChanged = source.readByte() != 0; moddedKeys = source.createBooleanArray(); byte[] tmp = source.createByteArray(); @@ -72,6 +74,7 @@ public class SaveKeyringParcel implements Parcelable { destination.writeSerializable(userIDs); //might not be the best method to store. destination.writeSerializable(originalIDs); destination.writeSerializable(deletedIDs); + destination.writeBooleanArray(newIDs); destination.writeByte((byte) (primaryIDChanged ? 1 : 0)); destination.writeBooleanArray(moddedKeys); byte[] tmp = null; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 2cdd64f4a..a9ab49c76 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -584,6 +584,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener saveParams.userIDs = getUserIds(mUserIdsView); saveParams.originalIDs = mUserIdsView.getOriginalIDs(); saveParams.deletedIDs = mUserIdsView.getDeletedIDs(); + saveParams.newIDs = toPrimitiveArray(mUserIdsView.getNewIDFlags()); saveParams.primaryIDChanged = mUserIdsView.primaryChanged(); saveParams.moddedKeys = toPrimitiveArray(mKeysView.getNeedsSavingArray()); saveParams.deletedKeys = mKeysView.getDeletedKeys(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 6c7737e6d..e99a4ef04 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -252,6 +252,16 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor return mList; } + public List getNewIDFlags() + { + ArrayList mList = new ArrayList(); + for (int i = 0; i < mEditors.getChildCount(); ++i) { + Editor editor = (Editor) mEditors.getChildAt(i); + mList.add(((UserIdEditor)editor).getIsNewID()); + } + return mList; + } + public List getNewKeysArray() { ArrayList mList = new ArrayList(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index d4b15613a..cf0cb6d44 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -261,4 +261,6 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene { return mOriginalID; } + + public boolean getIsNewID() { return mIsNewId; } } -- cgit v1.2.3 From 6d4a09f9890d152db32ce72c58a7a60d44a4ecae Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Wed, 2 Apr 2014 00:00:24 +0100 Subject: allow blank IDs, allow adding new IDs and let them be master --- .../java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 6 +++--- .../org/sufficientlysecure/keychain/ui/widget/SectionView.java | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 66f1f3f01..871b5b18b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -458,7 +458,7 @@ public class PgpKeyOperation { ArrayList> sigList = new ArrayList>(); for (String userId : saveParcel.userIDs) { String origID = saveParcel.originalIDs.get(userIDIndex); - if (origID.equals(userId) && !userId.equals(saveParcel.originalPrimaryID) && userIDIndex != 0) { + if ((origID.equals(userId) && !saveParcel.newIDs[userIDIndex]) && !userId.equals(saveParcel.originalPrimaryID) && userIDIndex != 0) { Iterator origSigs = masterPublicKey.getSignaturesForID(origID); //TODO: make sure this iterator only has signatures we are interested in while (origSigs.hasNext()) { PGPSignature origSig = origSigs.next(); @@ -489,7 +489,7 @@ public class PgpKeyOperation { } else { for (String userId : saveParcel.userIDs) { String origID = saveParcel.originalIDs.get(userIDIndex); - if (!origID.equals(userId)) { + if (!origID.equals(userId) || saveParcel.newIDs[userIDIndex]) { anyIDChanged = true; PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) @@ -516,7 +516,7 @@ public class PgpKeyOperation { userIDIndex = 0; for (String userId : saveParcel.userIDs) { String origID = saveParcel.originalIDs.get(userIDIndex); - if (!(origID.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged)) { + if (!(origID.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged) || !saveParcel.newIDs[userIDIndex]) { Iterator sigs = masterPublicKey.getSignaturesForID(userId); //TODO: make sure this iterator only has signatures we are interested in while (sigs.hasNext()) { PGPSignature sig = sigs.next(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index e99a4ef04..e6b22957b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -256,8 +256,11 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor { ArrayList mList = new ArrayList(); for (int i = 0; i < mEditors.getChildCount(); ++i) { - Editor editor = (Editor) mEditors.getChildAt(i); - mList.add(((UserIdEditor)editor).getIsNewID()); + UserIdEditor editor = (UserIdEditor) mEditors.getChildAt(i); + if (editor.isMainUserId()) + mList.add(0, editor.getIsNewID()); + else + mList.add(editor.getIsNewID()); } return mList; } -- cgit v1.2.3 From a38d22757c423bf182afaae2e5bce1d865e4f959 Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Wed, 2 Apr 2014 00:08:36 +0100 Subject: new ID sigs already added, so do save them --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 871b5b18b..ebed02d1b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -516,7 +516,7 @@ public class PgpKeyOperation { userIDIndex = 0; for (String userId : saveParcel.userIDs) { String origID = saveParcel.originalIDs.get(userIDIndex); - if (!(origID.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged) || !saveParcel.newIDs[userIDIndex]) { + if (!(origID.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged)) { Iterator sigs = masterPublicKey.getSignaturesForID(userId); //TODO: make sure this iterator only has signatures we are interested in while (sigs.hasNext()) { PGPSignature sig = sigs.next(); -- cgit v1.2.3 From 9764d3fcb98c782a9a16cb090eb019bd8e5e595e Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Wed, 2 Apr 2014 01:26:51 +0100 Subject: confirm that empty IDs are really wanted --- .../keychain/ui/EditKeyActivity.java | 47 +++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index a9ab49c76..633249d15 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -553,7 +553,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener showPassphraseDialog(masterKeyId); } else { mCurrentPassphrase = passphrase; - finallySaveClicked(); + checkEmptyIDsWanted(); } } catch (PgpGeneralException e) { Toast.makeText(this, getString(R.string.error_message, e.getMessage()), @@ -564,6 +564,51 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } } + private void checkEmptyIDsWanted() + { + try { + ArrayList userIDs = getUserIds(mUserIdsView); + List newIDs = mUserIdsView.getNewIDFlags(); + ArrayList originalIDs = mUserIdsView.getOriginalIDs(); + int curID = 0; + for (String userID : userIDs) { + if ( userID.equals("") && (!userID.equals(originalIDs.get(curID)) || newIDs.get(curID) ) ) { + AlertDialog.Builder alert = new AlertDialog.Builder( + EditKeyActivity.this); + + alert.setIcon(android.R.drawable.ic_dialog_alert); + alert.setTitle(R.string.warning); + alert.setMessage(EditKeyActivity.this.getString(R.string.ask_empty_id_ok)); + + alert.setPositiveButton(EditKeyActivity.this.getString(android.R.string.yes), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.dismiss(); + finallySaveClicked(); + } + } + ); + alert.setNegativeButton(this.getString(android.R.string.no), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.dismiss(); + } + } + ); + alert.setCancelable(false); + alert.create().show(); + return; + } + curID++; + } + } catch (PgpGeneralException e) { + Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage())); + Toast.makeText(this, getString(R.string.error_message, e.getMessage()), + Toast.LENGTH_SHORT).show(); + } + finallySaveClicked(); + } + private boolean[] toPrimitiveArray(final List booleanList) { final boolean[] primitives = new boolean[booleanList.size()]; int index = 0; -- cgit v1.2.3 From 5583fd513ee134cb5fbe4e96e6d9a1c823c3010f Mon Sep 17 00:00:00 2001 From: Ashley Hughes Date: Wed, 2 Apr 2014 01:28:53 +0100 Subject: always ask --- .../main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 633249d15..d1507fe34 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -290,7 +290,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { mCurrentPassphrase = PassphraseCacheService.getCachedPassphrase( EditKeyActivity.this, masterKeyId); - finallySaveClicked(); + checkEmptyIDsWanted(); } } }; -- cgit v1.2.3 From e92658f44d8ee5ca7d04c3dbb313150a7f33d6c3 Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Wed, 2 Apr 2014 01:34:24 +0200 Subject: Adjust import order --- .../keychain/KeychainApplication.java | 11 +++++----- .../compatibility/ClipboardReflection.java | 4 ++-- .../keychain/helper/ExportHelper.java | 6 ------ .../keychain/pgp/PgpKeyOperation.java | 3 +++ .../keychain/provider/KeychainDatabase.java | 2 +- .../keychain/remote/AppSettings.java | 4 ---- .../keychain/remote/ui/AccountsListFragment.java | 2 -- .../keychain/remote/ui/AppsListFragment.java | 2 -- .../keychain/service/KeychainIntentService.java | 2 -- .../keychain/service/PassphraseCacheService.java | 4 +++- .../keychain/ui/CertifyKeyActivity.java | 1 - .../keychain/ui/EditKeyActivity.java | 1 + .../keychain/ui/ImportKeysQrCodeFragment.java | 5 ++++- .../keychain/ui/ViewKeyActivity.java | 1 - .../keychain/ui/ViewKeyMainFragment.java | 1 - .../keychain/ui/adapter/ImportKeysAdapter.java | 1 - .../keychain/ui/adapter/PagerTabStripAdapter.java | 4 ---- .../keychain/ui/adapter/ViewKeyKeysAdapter.java | 1 - .../keychain/ui/widget/KeyEditor.java | 25 ++++++++-------------- .../keychain/ui/widget/SectionView.java | 24 ++++++--------------- .../keychain/ui/widget/UserIdEditor.java | 9 ++++---- .../keychain/util/HkpKeyServer.java | 5 +---- .../keychain/util/IntentIntegratorSupportV4.java | 3 ++- .../keychain/util/QrCodeUtils.java | 6 ++++-- 24 files changed, 46 insertions(+), 81 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index 98b827542..e4ce6c373 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -17,16 +17,17 @@ package org.sufficientlysecure.keychain; -import java.io.File; -import java.security.Provider; -import java.security.Security; +import android.app.Application; +import android.os.Environment; import org.spongycastle.jce.provider.BouncyCastleProvider; + import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.PRNGFixes; -import android.app.Application; -import android.os.Environment; +import java.io.File; +import java.security.Provider; +import java.security.Security; public class KeychainApplication extends Application { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java index 3164de7d1..10bb8cf5d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java @@ -17,13 +17,13 @@ package org.sufficientlysecure.keychain.compatibility; -import java.lang.reflect.Method; - import android.content.Context; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.util.Log; +import java.lang.reflect.Method; + public class ClipboardReflection { private static final String clipboardLabel = "Keychain"; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java index cc240a67b..00a62ce58 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java @@ -30,18 +30,12 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; -import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; import org.sufficientlysecure.keychain.util.Log; -import java.lang.reflect.Array; -import java.security.Provider; -import java.util.ArrayList; - public class ExportHelper { protected FileDialogFragment mFileDialog; protected String mExportFilename; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index ebed02d1b..c91a932c5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -17,6 +17,8 @@ package org.sufficientlysecure.keychain.pgp; +import android.util.Pair; + import org.spongycastle.bcpg.CompressionAlgorithmTags; import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; @@ -45,6 +47,7 @@ import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBu import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair; import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 8c33844b2..807444d78 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -23,8 +23,8 @@ import android.database.sqlite.SQLiteOpenHelper; import android.provider.BaseColumns; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java index 6c7e51bf0..a3f9f84c9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java @@ -17,10 +17,6 @@ package org.sufficientlysecure.keychain.remote; -import org.spongycastle.bcpg.HashAlgorithmTags; -import org.spongycastle.openpgp.PGPEncryptedData; -import org.sufficientlysecure.keychain.Id; - public class AppSettings { private String mPackageName; private byte[] mPackageSignature; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java index 8e65a2f04..cfc9c92ad 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java @@ -32,12 +32,10 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; -import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.ui.widget.FixedListView; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java index f3fa6e7c6..22082e913 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java @@ -37,11 +37,9 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.ImageView; import android.widget.TextView; -import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; -import org.sufficientlysecure.keychain.util.Log; public class AppsListFragment extends ListFragment implements LoaderManager.LoaderCallbacks { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 110f06634..bdd50c98d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -36,8 +36,6 @@ import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.pgp.*; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; -import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; import org.sufficientlysecure.keychain.util.*; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index 5825db01b..7ab40491f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -25,14 +25,16 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.*; -import android.util.Log; import android.support.v4.util.LongSparseArray; +import android.util.Log; + import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.helper.Preferences; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index 5dc06c16d..9e32fead0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -38,7 +38,6 @@ import com.beardedhen.androidbootstrap.BootstrapButton; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index d1507fe34..bab1e6f5f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -47,6 +47,7 @@ import com.devspark.appmsg.AppMsg; import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java index 10c0752b1..8b553d273 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java @@ -17,6 +17,8 @@ package org.sufficientlysecure.keychain.ui; +import com.google.zxing.integration.android.IntentResult; + import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -28,8 +30,9 @@ import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; + import com.beardedhen.androidbootstrap.BootstrapButton; -import com.google.zxing.integration.android.IntentResult; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.util.IntentIntegratorSupportV4; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 3e7e6d7ce..b9dcd2e21 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -38,7 +38,6 @@ import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter; -import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.ShareQrCodeDialogFragment; import org.sufficientlysecure.keychain.util.Log; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index 691be5fa9..8670241f6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -37,7 +37,6 @@ import com.beardedhen.androidbootstrap.BootstrapButton; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 7d3166af9..8cb321109 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -32,7 +32,6 @@ import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import java.util.ArrayList; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java index 3e7952beb..4a3796f01 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java @@ -21,10 +21,6 @@ import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentPagerAdapter; -import android.support.v4.app.FragmentStatePagerAdapter; -import android.support.v4.app.FragmentTransaction; -import android.support.v4.view.ViewPager; -import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity; import java.util.ArrayList; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java index 9d60c1530..cf7ed670d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java @@ -20,7 +20,6 @@ package org.sufficientlysecure.keychain.ui.adapter; import android.content.Context; import android.content.res.ColorStateList; import android.database.Cursor; -import android.graphics.Color; import android.support.v4.widget.CursorAdapter; import android.text.format.DateFormat; import android.view.LayoutInflater; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 038f8507e..f4dad3edf 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -16,20 +16,6 @@ package org.sufficientlysecure.keychain.ui.widget; -import java.text.DateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.TimeZone; -import java.util.Vector; - -import org.spongycastle.bcpg.sig.KeyFlags; -import org.spongycastle.openpgp.PGPKeyFlags; -import org.spongycastle.openpgp.PGPPublicKey; -import org.spongycastle.openpgp.PGPSecretKey; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.util.Choice; import android.annotation.TargetApi; import android.app.DatePickerDialog; import android.app.Dialog; @@ -47,16 +33,23 @@ import android.widget.LinearLayout; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; + import com.beardedhen.androidbootstrap.BootstrapButton; + +import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPSecretKey; -import org.sufficientlysecure.keychain.Id; + import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.util.Choice; import java.text.DateFormat; -import java.util.*; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; +import java.util.Vector; public class KeyEditor extends LinearLayout implements Editor, OnClickListener { private PGPSecretKey mKey; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index e6b22957b..c04cc7674 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -16,23 +16,6 @@ package org.sufficientlysecure.keychain.ui.widget; -import java.util.ArrayList; -import java.util.List; -import java.util.Vector; - -import org.spongycastle.openpgp.PGPKeyFlags; -import org.spongycastle.openpgp.PGPSecretKey; -import org.sufficientlysecure.keychain.Id; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; -import org.sufficientlysecure.keychain.service.KeychainIntentService; -import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; -import org.sufficientlysecure.keychain.service.PassphraseCacheService; -import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; -import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener; -import org.sufficientlysecure.keychain.util.Choice; - -import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; @@ -49,7 +32,10 @@ import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; + +import org.spongycastle.openpgp.PGPKeyFlags; import org.spongycastle.openpgp.PGPSecretKey; + import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; @@ -61,7 +47,9 @@ import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener; import org.sufficientlysecure.keychain.util.Choice; - +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; public class SectionView extends LinearLayout implements OnClickListener, EditorListener, Editor { private LayoutInflater mInflater; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index cf0cb6d44..52a78f9ad 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -16,11 +16,6 @@ package org.sufficientlysecure.keychain.ui.widget; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import android.content.Context; import android.text.Editable; import android.text.TextWatcher; @@ -31,8 +26,12 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.*; import com.beardedhen.androidbootstrap.BootstrapButton; + +import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ContactHelper; +import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import java.util.regex.Matcher; public class UserIdEditor extends LinearLayout implements Editor, OnClickListener { private EditorListener mEditorListener = null; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index b987e1533..e4171cfae 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -31,7 +31,6 @@ import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.PgpHelper; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; import java.io.ByteArrayOutputStream; @@ -43,8 +42,6 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry.getAlgorithmFromId; - public class HkpKeyServer extends KeyServer { private static class HttpError extends Exception { private static final long serialVersionUID = 1718783705229428893L; @@ -244,7 +241,7 @@ public class HkpKeyServer extends KeyServer { entry.setBitStrength(Integer.parseInt(matcher.group(3))); final int algorithmId = Integer.decode(matcher.group(2)); - entry.setAlgorithm(getAlgorithmFromId(algorithmId)); + entry.setAlgorithm(ImportKeysListEntry.getAlgorithmFromId(algorithmId)); // group 1 contains the full fingerprint (v4) or the long key id if available // see https://bitbucket.org/skskeyserver/sks-keyserver/pull-request/12/fixes-for-machine-readable-indexes/diff diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IntentIntegratorSupportV4.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IntentIntegratorSupportV4.java index b95b3ee6a..ae87deb31 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IntentIntegratorSupportV4.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IntentIntegratorSupportV4.java @@ -16,9 +16,10 @@ package org.sufficientlysecure.keychain.util; +import com.google.zxing.integration.android.IntentIntegrator; + import android.content.Intent; import android.support.v4.app.Fragment; -import com.google.zxing.integration.android.IntentIntegrator; /** * IntentIntegrator for the V4 Android compatibility package. diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/QrCodeUtils.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/QrCodeUtils.java index 8c3367bea..af9034aa7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/QrCodeUtils.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/QrCodeUtils.java @@ -18,14 +18,16 @@ package org.sufficientlysecure.keychain.util; -import android.graphics.Bitmap; -import android.graphics.Color; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; + +import android.graphics.Bitmap; +import android.graphics.Color; + import org.sufficientlysecure.keychain.Constants; import java.util.Hashtable; -- cgit v1.2.3 From 8e503bd263d451234f92b843987cb0d12cfbee3a Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Wed, 2 Apr 2014 01:36:13 +0200 Subject: Adjust copyright headers --- .../keychain/helper/Preferences.java | 2 +- .../keychain/ui/CertifyKeyActivity.java | 2 +- .../keychain/ui/ImportKeysActivity.java | 2 +- .../keychain/util/InputData.java | 2 ++ .../keychain/util/KeychainServiceListener.java | 22 +++++++++++++--------- .../keychain/util/PositionAwareInputStream.java | 2 ++ 6 files changed, 20 insertions(+), 12 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java index 515201b92..a9b773371 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java @@ -1,7 +1,7 @@ /* * Copyright (C) 2012 Dominik Schürmann * Copyright (C) 2010 Thialfihar - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index 9e32fead0..f551ee5c1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -1,7 +1,7 @@ /* * Copyright (C) 2014 Dominik Schürmann * Copyright (C) 2011 Senecaso - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 834509f53..b73510e38 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -1,7 +1,7 @@ /* * Copyright (C) 2012-2014 Dominik Schürmann * Copyright (C) 2011 Senecaso - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java index 092c14e00..28cfa11f2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java @@ -1,4 +1,6 @@ /* + * Copyright (C) 2010-2014 Thialfihar + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeychainServiceListener.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeychainServiceListener.java index 14b2a2211..b205bd556 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeychainServiceListener.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeychainServiceListener.java @@ -1,16 +1,20 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Copyright (C) 2014 Dominik Schürmann * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, either version 3 of the License, or + * (at your option) any later version. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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, see . */ + package org.sufficientlysecure.keychain.util; public interface KeychainServiceListener { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PositionAwareInputStream.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PositionAwareInputStream.java index a783d7820..4fcd3047f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PositionAwareInputStream.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PositionAwareInputStream.java @@ -1,4 +1,6 @@ /* + * Copyright (C) 2010-2014 Thialfihar + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at -- cgit v1.2.3 From dd4a1e3f5239cc35a1abdc625238361350155191 Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Wed, 2 Apr 2014 01:43:40 +0200 Subject: Trivial spacing changes to conform to style guide --- .../sufficientlysecure/keychain/KeychainApplication.java | 4 ++-- .../keychain/compatibility/ClipboardReflection.java | 4 ++-- .../sufficientlysecure/keychain/helper/ExportHelper.java | 2 +- .../keychain/pgp/PgpConversionHelper.java | 10 ++++++---- .../sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 10 +++++----- .../keychain/provider/ProviderHelper.java | 5 +++-- .../keychain/remote/ui/RemoteServiceActivity.java | 2 +- .../keychain/service/KeychainIntentService.java | 2 +- .../keychain/service/SaveKeyringParcel.java | 16 ++++++++-------- .../keychain/ui/CertifyKeyActivity.java | 2 +- .../keychain/ui/DecryptFileFragment.java | 2 +- .../sufficientlysecure/keychain/ui/DrawerActivity.java | 10 +++++----- .../sufficientlysecure/keychain/ui/EditKeyActivity.java | 2 +- .../keychain/ui/EncryptFileFragment.java | 5 +++-- .../keychain/ui/ImportKeysClipboardFragment.java | 2 +- .../sufficientlysecure/keychain/ui/KeyListFragment.java | 2 +- .../keychain/ui/SelectSecretKeyFragment.java | 3 ++- .../keychain/ui/SelectSecretKeyLayoutFragment.java | 10 +++++----- .../sufficientlysecure/keychain/ui/ViewKeyActivity.java | 2 +- .../keychain/ui/adapter/ViewKeyKeysAdapter.java | 3 +-- .../keychain/ui/adapter/ViewKeyUserIdsAdapter.java | 14 ++++++++------ .../keychain/ui/dialog/CreateKeyDialogFragment.java | 7 ++++--- .../keychain/ui/dialog/DeleteKeyDialogFragment.java | 9 ++------- .../keychain/ui/widget/FoldableLinearLayout.java | 14 +++++++------- .../sufficientlysecure/keychain/ui/widget/KeyEditor.java | 16 ++++++++-------- .../keychain/ui/widget/SectionView.java | 4 ++-- .../keychain/ui/widget/UserIdEditor.java | 6 +++--- .../keychain/util/IterableIterator.java | 2 +- .../sufficientlysecure/keychain/util/ProgressScaler.java | 2 +- 29 files changed, 87 insertions(+), 85 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index e4ce6c373..9b80e76f3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -41,14 +41,14 @@ public class KeychainApplication extends Application { /* * Sets Bouncy (Spongy) Castle as preferred security provider - * + * * insertProviderAt() position starts from 1 */ Security.insertProviderAt(new BouncyCastleProvider(), 1); /* * apply RNG fixes - * + * * among other things, executes Security.insertProviderAt(new * LinuxPRNGSecureRandomProvider(), 1) for Android <= SDK 17 */ diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java index 10bb8cf5d..1cac5762d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java @@ -30,7 +30,7 @@ public class ClipboardReflection { /** * Wrapper around ClipboardManager based on Android version using Reflection API - * + * * @param context * @param text */ @@ -57,7 +57,7 @@ public class ClipboardReflection { /** * Wrapper around ClipboardManager based on Android version using Reflection API - * + * * @param context */ public static CharSequence getClipboardText(Context context) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java index 00a62ce58..43fdc7751 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java @@ -75,7 +75,7 @@ public class ExportHelper { int type = keyType; mExportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); - if( data.getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED) ) { + if (data.getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED)) { type = Id.type.public_secret_key; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java index 1f8dec7a1..7c25c2c2a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java @@ -65,14 +65,16 @@ public class PgpConversionHelper { try { while ((obj = factory.nextObject()) != null) { PGPSecretKey secKey = null; - if(obj instanceof PGPSecretKey) { - if ((secKey = (PGPSecretKey)obj ) == null) { + if (obj instanceof PGPSecretKey) { + secKey = (PGPSecretKey) obj; + if (secKey == null) { Log.e(Constants.TAG, "No keys given!"); } keys.add(secKey); - } else if(obj instanceof PGPSecretKeyRing) { //master keys are sent as keyrings + } else if (obj instanceof PGPSecretKeyRing) { //master keys are sent as keyrings PGPSecretKeyRing keyRing = null; - if ((keyRing = (PGPSecretKeyRing)obj) == null) { + keyRing = (PGPSecretKeyRing) obj; + if (keyRing == null) { Log.e(Constants.TAG, "No keys given!"); } @SuppressWarnings("unchecked") diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index c91a932c5..d4fba68ff 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -219,7 +219,7 @@ public class PgpKeyOperation { } - private Pair buildNewSecretKey( + private Pair buildNewSecretKey( ArrayList userIds, ArrayList keys, ArrayList keysExpiryDates, ArrayList keysUsages, @@ -359,11 +359,11 @@ public class PgpKeyOperation { PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing(); PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing(); - return new Pair(secretKeyRing, publicKeyRing); + return new Pair(secretKeyRing, publicKeyRing); } - public Pair buildSecretKey (PGPSecretKeyRing mKR, + public Pair buildSecretKey(PGPSecretKeyRing mKR, PGPPublicKeyRing pKR, SaveKeyringParcel saveParcel) throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException { @@ -676,7 +676,7 @@ public class PgpKeyOperation { */ - return new Pair(mKR, pKR); + return new Pair(mKR, pKR); } @@ -723,7 +723,7 @@ public class PgpKeyOperation { } // fetch public key ring, add the certification and return it - for(String userId : new IterableIterator(userIds.iterator())) { + for (String userId : new IterableIterator(userIds.iterator())) { PGPSignature sig = signatureGenerator.generateCertification(userId, publicKey); publicKey = PGPPublicKey.addCertification(publicKey, userId, sig); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 13dc2af2b..c88e3e22f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -508,13 +508,14 @@ public class ProviderHelper { */ public static boolean getMasterKeyCanCertify(Context context, Uri queryUri) { - String[] projection = new String[]{ + String[] projection = new String[] { KeyRings.MASTER_KEY_ID, "(SELECT COUNT(sign_keys." + Keys._ID + ") FROM " + Tables.KEYS + " AS sign_keys WHERE sign_keys." + Keys.KEY_RING_ROW_ID + " = " + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID + " AND sign_keys." + Keys.CAN_CERTIFY + " = '1' AND " + Keys.IS_MASTER_KEY - + " = 1) AS sign",}; + + " = 1) AS sign", + }; ContentResolver cr = context.getContentResolver(); Cursor cursor = cr.query(queryUri, projection, null, null, null); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java index a894da448..b2ab75cea 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java @@ -95,7 +95,7 @@ public class RemoteServiceActivity extends ActionBarActivity { if (ACTION_REGISTER.equals(action)) { final String packageName = extras.getString(EXTRA_PACKAGE_NAME); final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE); - Log.d(Constants.TAG, "ACTION_REGISTER packageName: "+packageName); + Log.d(Constants.TAG, "ACTION_REGISTER packageName: " + packageName); // Inflate a "Done"/"Cancel" custom action bar view ActionBarHelper.setTwoButtonView(getSupportActionBar(), diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index bdd50c98d..14beae40c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -818,7 +818,7 @@ public class KeychainIntentService extends IntentService return; } // contextualize the exception, if necessary - if(e instanceof PgpGeneralMsgIdException) { + if (e instanceof PgpGeneralMsgIdException) { e = ((PgpGeneralMsgIdException) e).getContextualized(this); } Log.e(Constants.TAG, "ApgService Exception: ", e); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index b7ae4e1f1..cc0f94b9b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -46,20 +46,20 @@ public class SaveKeyringParcel implements Parcelable { public SaveKeyringParcel() {} - private SaveKeyringParcel(Parcel source) - { - userIDs = (ArrayList)source.readSerializable(); - originalIDs = (ArrayList)source.readSerializable(); - deletedIDs = (ArrayList)source.readSerializable(); + private SaveKeyringParcel(Parcel source) { + userIDs = (ArrayList) source.readSerializable(); + originalIDs = (ArrayList) source.readSerializable(); + deletedIDs = (ArrayList) source.readSerializable(); newIDs = source.createBooleanArray(); primaryIDChanged = source.readByte() != 0; moddedKeys = source.createBooleanArray(); byte[] tmp = source.createByteArray(); - if (tmp == null) + if (tmp == null) { deletedKeys = null; - else + } else { deletedKeys = PgpConversionHelper.BytesToPGPSecretKeyList(tmp); - keysExpiryDates = (ArrayList)source.readSerializable(); + } + keysExpiryDates = (ArrayList) source.readSerializable(); keysUsages = source.readArrayList(Integer.class.getClassLoader()); newPassPhrase = source.readString(); oldPassPhrase = source.readString(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index f551ee5c1..d041bc35e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -306,7 +306,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements // Bail out if there is not at least one user id selected ArrayList userIds = mUserIdsAdapter.getSelectedUserIds(); - if(userIds.isEmpty()) { + if (userIds.isEmpty()) { Toast.makeText(CertifyKeyActivity.this, "No User IDs to sign selected!", Toast.LENGTH_SHORT).show(); return; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index ed6366353..67cf8d3e3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -205,7 +205,7 @@ public class DecryptFileFragment extends DecryptFragment { } else { AppMsg.makeText(getActivity(), R.string.decryption_successful, AppMsg.STYLE_INFO).show(); - + if (mDeleteAfter.isChecked()) { // Create and show dialog to delete original file DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java index f01e67449..e5a8fa8bc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java @@ -58,7 +58,7 @@ public class DrawerActivity extends ActionBarActivity { // if the left margin of the loaded layout is close to the // one used in tablets then set drawer as open and locked - if( Math.abs(leftMarginLoaded - leftMarginInTablets) < errorInMarginAllowed) { + if (Math.abs(leftMarginLoaded - leftMarginInTablets) < errorInMarginAllowed) { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, mDrawerList); mDrawerLayout.setScrimColor(Color.TRANSPARENT); mIsDrawerLocked = true; @@ -82,7 +82,7 @@ public class DrawerActivity extends ActionBarActivity { // enable ActionBar app icon to behave as action to toggle nav drawer // if the drawer is not locked - if ( !mIsDrawerLocked ) { + if (!mIsDrawerLocked) { getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); } @@ -109,7 +109,7 @@ public class DrawerActivity extends ActionBarActivity { } }; - if ( !mIsDrawerLocked ) { + if (!mIsDrawerLocked) { mDrawerLayout.setDrawerListener(mDrawerToggle); } else { // If the drawer is locked open make it un-focusable @@ -218,9 +218,9 @@ public class DrawerActivity extends ActionBarActivity { // setTitle(mDrawerTitles[position]); // If drawer isn't locked just close the drawer and // it will move to the selected item by itself (via drawer toggle listener) - if ( !mIsDrawerLocked ) { + if (!mIsDrawerLocked) { mDrawerLayout.closeDrawer(mDrawerList); - // else move to the selected item yourself + // else move to the selected item yourself } else { callIntentForDrawerItem(mSelectedItem); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index bab1e6f5f..8ef4631dc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -339,7 +339,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener Toast.makeText(this, R.string.error_save_first, Toast.LENGTH_LONG).show(); } else { long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri); - long[] ids = new long[]{masterKeyId}; + long[] ids = new long[] {masterKeyId}; mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC, null); return true; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java index fb727d297..cee7dae87 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java @@ -112,7 +112,7 @@ public class EncryptFileFragment extends Fragment { }); mFileCompression = (Spinner) view.findViewById(R.id.fileCompression); - Choice[] choices = new Choice[]{ + Choice[] choices = new Choice[] { new Choice(Id.choice.compression.none, getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")"), new Choice(Id.choice.compression.zip, "ZIP (" @@ -120,7 +120,8 @@ public class EncryptFileFragment extends Fragment { new Choice(Id.choice.compression.zlib, "ZLIB (" + getString(R.string.compression_fast) + ")"), new Choice(Id.choice.compression.bzip2, "BZIP2 (" - + getString(R.string.compression_very_slow) + ")"),}; + + getString(R.string.compression_very_slow) + ")"), + }; ArrayAdapter adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_spinner_item, choices); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java index e53762580..28e2091a9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java @@ -65,7 +65,7 @@ public class ImportKeysClipboardFragment extends Fragment { String sendText = ""; if (clipboardText != null) { sendText = clipboardText.toString(); - if(sendText.toLowerCase(Locale.ENGLISH).startsWith(Constants.FINGERPRINT_SCHEME)) { + if (sendText.toLowerCase(Locale.ENGLISH).startsWith(Constants.FINGERPRINT_SCHEME)) { mImportActivity.loadFromFingerprintUri(null, Uri.parse(sendText)); return; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 957c822d2..6da8a0262 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -185,7 +185,7 @@ public class KeyListFragment extends Fragment } case R.id.menu_key_list_multi_export: { ids = mStickyList.getWrappedList().getCheckedItemIds(); - long[] masterKeyIds = new long[2*ids.length]; + long[] masterKeyIds = new long[2 * ids.length]; ArrayList allPubRowIds = ProviderHelper.getPublicKeyRingsRowIds(getActivity()); for (int i = 0; i < ids.length; i++) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java index 2efa7d33a..1f0a1a197 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java @@ -141,7 +141,8 @@ public class SelectSecretKeyFragment extends ListFragment implements + Keys.IS_REVOKED + " = '0' AND valid_keys." + Keys.CAN_SIGN + " = '1' AND valid_keys." + Keys.CREATION + " <= '" + now + "' AND " + "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys." + Keys.EXPIRY - + " >= '" + now + "')) AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID,}; + + " >= '" + now + "')) AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, + }; String orderBy = UserIds.USER_ID + " ASC"; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java index d1ba431d6..f0704bb0f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java @@ -53,12 +53,12 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan private SelectSecretKeyCallback mCallback; - final String[] PROJECTION = new String[]{ - KeychainContract.UserIds.USER_ID, - KeychainContract.KeyRings.MASTER_KEY_ID + private static final String[] PROJECTION = new String[] { + KeychainContract.UserIds.USER_ID, + KeychainContract.KeyRings.MASTER_KEY_ID, }; - final int INDEX_USER_ID = 0; - final int INDEX_MASTER_KEY_ID = 1; + private static final int INDEX_USER_ID = 0; + private static final int INDEX_MASTER_KEY_ID = 1; public interface SelectSecretKeyCallback { void onKeySelected(long secretKeyId); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index b9dcd2e21..b86c20880 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -125,7 +125,7 @@ public class ViewKeyActivity extends ActionBarActivity { case R.id.menu_key_view_export_file: long masterKeyId = ProviderHelper.getPublicMasterKeyId(this, Long.valueOf(mDataUri.getLastPathSegment())); - long[] ids = new long[]{masterKeyId}; + long[] ids = new long[] {masterKeyId}; mExportHelper.showExportKeysDialog(ids, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB, null); return true; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java index cf7ed670d..99a4d38e9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java @@ -148,8 +148,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter { DateFormat.getDateFormat(context).format(expiryDate) + ")"); keyExpiry.setVisibility(View.VISIBLE); - } - else { + } else { keyExpiry.setVisibility(View.GONE); } // if key is expired or revoked, strike through text diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java index 61572b9ce..21a150606 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java @@ -55,14 +55,15 @@ public class ViewKeyUserIdsAdapter extends CursorAdapter { @Override public Cursor swapCursor(Cursor newCursor) { initIndex(newCursor); - if(mCheckStates != null) { + if (mCheckStates != null) { mCheckStates.clear(); - if(newCursor != null) { + if (newCursor != null) { int count = newCursor.getCount(); mCheckStates.ensureCapacity(count); // initialize to true (use case knowledge: we usually want to sign all uids) - for(int i = 0; i < count; i++) + for (int i = 0; i < count; i++) { mCheckStates.add(true); + } } } @@ -100,8 +101,9 @@ public class ViewKeyUserIdsAdapter extends CursorAdapter { vAddress.setText(userId[1]); // don't care further if checkboxes aren't shown - if(mCheckStates == null) + if (mCheckStates == null) { return; + } final CheckBox vCheckBox = (CheckBox) view.findViewById(R.id.checkBox); final int position = cursor.getPosition(); @@ -124,8 +126,8 @@ public class ViewKeyUserIdsAdapter extends CursorAdapter { public ArrayList getSelectedUserIds() { ArrayList result = new ArrayList(); - for(int i = 0; i < mCheckStates.size(); i++) { - if(mCheckStates.get(i)) { + for (int i = 0; i < mCheckStates.size(); i++) { + if (mCheckStates.get(i)) { mCursor.moveToPosition(i); result.add(mCursor.getString(mIndexUserId)); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java index ffb45afc5..ad558a81e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java @@ -138,9 +138,10 @@ public class CreateKeyDialogFragment extends DialogFragment { final AdapterView.OnItemSelectedListener weakRsaListener = new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { - final Choice selectedAlgorithm = (Choice)algorithm.getSelectedItem(); - final int selectedKeySize = Integer.parseInt((String)keySize.getSelectedItem()); - final boolean isWeakRsa = (selectedAlgorithm.getId() == Id.choice.algorithm.rsa && selectedKeySize <= 1024); + final Choice selectedAlgorithm = (Choice) algorithm.getSelectedItem(); + final int selectedKeySize = Integer.parseInt((String) keySize.getSelectedItem()); + final boolean isWeakRsa = (selectedAlgorithm.getId() == Id.choice.algorithm.rsa && + selectedKeySize <= 1024); alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(!isWeakRsa); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index 3ff88aa2b..60dea2a41 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -184,12 +184,10 @@ public class DeleteKeyDialogFragment extends DialogFragment { if (cursor == null || cursor.getCount() == 0 || !checkDeleteSecret.isChecked()) { isSuccessfullyDeleted = true; } - } finally { if (cursor != null) { cursor.close(); } - } dismiss(); @@ -200,9 +198,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { sendMessageToHandler(MESSAGE_ERROR, null); } } - - } - ); + }); builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override @@ -232,5 +228,4 @@ public class DeleteKeyDialogFragment extends DialogFragment { Log.w(Constants.TAG, "Messenger is null!", e); } } - -} \ No newline at end of file +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java index f9a5b92f3..6b2f3bf06 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java @@ -82,7 +82,7 @@ public class FoldableLinearLayout extends LinearLayout { * @param attrs */ private void processAttributes(Context context, AttributeSet attrs) { - if(attrs != null) { + if (attrs != null) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FoldableLinearLayout, 0, 0); mFoldedIconName = a.getString(R.styleable.FoldableLinearLayout_foldedIcon); @@ -102,7 +102,7 @@ public class FoldableLinearLayout extends LinearLayout { protected void onFinishInflate() { // if the migration has already happened // there is no need to move any children - if(!mHasMigrated) { + if (!mHasMigrated) { migrateChildrenToContainer(); mHasMigrated = true; } @@ -120,10 +120,10 @@ public class FoldableLinearLayout extends LinearLayout { int childNum = getChildCount(); View[] children = new View[childNum]; - for(int i = 0; i < childNum; i++) { + for (int i = 0; i < childNum; i++) { children[i] = getChildAt(i); } - if(children[0].getId() == R.id.foldableControl) { + if (children[0].getId() == R.id.foldableControl) { } @@ -131,14 +131,14 @@ public class FoldableLinearLayout extends LinearLayout { detachAllViewsFromParent(); // Inflate the inner foldable_linearlayout.xml - LayoutInflater inflator = (LayoutInflater)getContext().getSystemService( + LayoutInflater inflator = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE); mFoldableLayout = inflator.inflate(R.layout.foldable_linearlayout, this, true); mFoldableContainer = (LinearLayout) mFoldableLayout.findViewById(R.id.foldableContainer); // Push previously collected children into foldableContainer. - for(int i = 0; i < childNum; i++) { + for (int i = 0; i < childNum; i++) { addView(children[i]); } } @@ -196,7 +196,7 @@ public class FoldableLinearLayout extends LinearLayout { */ @Override public void addView(View child) { - if(mFoldableContainer != null) { + if (mFoldableContainer != null) { mFoldableContainer.addView(child); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index f4dad3edf..1f5b13c83 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -148,7 +148,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { date = new GregorianCalendar(TimeZone.getTimeZone("UTC")); } /* - * Using custom DatePickerDialog which overrides the setTitle because + * Using custom DatePickerDialog which overrides the setTitle because * the DatePickerDialog title is buggy (unix warparound bug). * See: https://code.google.com/p/android/issues/detail?id=49066 */ @@ -221,23 +221,23 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { boolean isDSAKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.DSA); if (isElGamalKey) { mChkSign.setVisibility(View.INVISIBLE); - TableLayout table = (TableLayout)findViewById(R.id.table_keylayout); - TableRow row = (TableRow)findViewById(R.id.row_sign); + TableLayout table = (TableLayout) findViewById(R.id.table_keylayout); + TableRow row = (TableRow) findViewById(R.id.row_sign); table.removeView(row); } if (isDSAKey) { mChkEncrypt.setVisibility(View.INVISIBLE); - TableLayout table = (TableLayout)findViewById(R.id.table_keylayout); - TableRow row = (TableRow)findViewById(R.id.row_encrypt); + TableLayout table = (TableLayout) findViewById(R.id.table_keylayout); + TableRow row = (TableRow) findViewById(R.id.row_encrypt); table.removeView(row); } if (!mIsMasterKey) { mChkCertify.setVisibility(View.INVISIBLE); - TableLayout table = (TableLayout)findViewById(R.id.table_keylayout); - TableRow row = (TableRow)findViewById(R.id.row_certify); + TableLayout table = (TableLayout) findViewById(R.id.table_keylayout); + TableRow row = (TableRow) findViewById(R.id.row_certify); table.removeView(row); } else { - TextView mLabelUsage2= (TextView) findViewById(R.id.label_usage2); + TextView mLabelUsage2 = (TextView) findViewById(R.id.label_usage2); mLabelUsage2.setVisibility(View.INVISIBLE); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index c04cc7674..272f43915 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -195,8 +195,8 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor for (int i = 0; i < mEditors.getChildCount(); ++i) { Editor editor = (Editor) mEditors.getChildAt(i); if (mType == Id.type.user_id) { - if(((UserIdEditor)editor).getIsOriginallyMainUserID()) { - return ((UserIdEditor)editor).getOriginalID(); + if (((UserIdEditor) editor).getIsOriginallyMainUserID()) { + return ((UserIdEditor) editor).getOriginalID(); } } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index 52a78f9ad..71f5f0d86 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -239,9 +239,9 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene @Override public boolean needsSaving() { boolean retval = false; //(mOriginallyMainUserID != isMainUserId()); - retval |= !(mOriginalName.equals( ("" + mName.getText()).trim() ) ); - retval |= !(mOriginalEmail.equals( ("" + mEmail.getText()).trim() ) ); - retval |= !(mOriginalComment.equals( ("" + mComment.getText()).trim() ) ); + retval |= !(mOriginalName.equals(("" + mName.getText()).trim())); + retval |= !(mOriginalEmail.equals(("" + mEmail.getText()).trim())); + retval |= !(mOriginalComment.equals(("" + mComment.getText()).trim())); retval |= mIsNewId; return retval; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IterableIterator.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IterableIterator.java index 40105df4f..3af674526 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IterableIterator.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IterableIterator.java @@ -24,7 +24,7 @@ public class IterableIterator implements Iterable { public IterableIterator(Iterator iter, boolean failsafe) { mIter = iter; - if(failsafe && mIter == null) { + if (failsafe && mIter == null) { // is there a better way? mIter = new ArrayList().iterator(); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java index 15b70e22e..23961c05f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java @@ -36,7 +36,7 @@ public class ProgressScaler implements ProgressDialogUpdater { * Set progressDialogUpdater of ProgressDialog by sending message to handler on UI thread */ public void setProgress(String message, int progress, int max) { - mWrapped.setProgress(message, mFrom+ progress*(mTo-mFrom)/max, mMax); + mWrapped.setProgress(message, mFrom + progress * (mTo - mFrom) / max, mMax); } public void setProgress(int resourceId, int progress, int max) { -- cgit v1.2.3 From d5983b324f107ef274d1af774787d0d5acf50131 Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Wed, 2 Apr 2014 01:51:02 +0200 Subject: Adjust variable/member naming to conform to style guide In some cases change member accessibility, so the naming matches. Also, some key words were reordered to comply with JLS suggestions. --- .../keychain/helper/Preferences.java | 8 ++-- .../pgp/exception/PgpGeneralMsgIdException.java | 10 ++--- .../keychain/ui/EncryptAsymmetricFragment.java | 4 +- .../keychain/ui/PreferencesActivity.java | 44 +++++++++---------- .../keychain/ui/adapter/ImportKeysAdapter.java | 12 ++--- .../keychain/ui/adapter/ImportKeysListEntry.java | 2 +- .../keychain/ui/adapter/PagerTabStripAdapter.java | 6 +-- .../keychain/ui/adapter/TabsAdapter.java | 4 +- .../keychain/ui/adapter/ViewKeyUserIdsAdapter.java | 2 +- .../ui/dialog/DeleteKeyDialogFragment.java | 51 ++++++++++++---------- .../keychain/ui/widget/SectionView.java | 18 ++++---- 11 files changed, 82 insertions(+), 79 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java index a9b773371..13b1df4d4 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java @@ -30,7 +30,7 @@ import java.util.Vector; * Singleton Implementation of a Preference Helper */ public class Preferences { - private static Preferences mPreferences; + private static Preferences sPreferences; private SharedPreferences mSharedPreferences; public static synchronized Preferences getPreferences(Context context) { @@ -38,10 +38,10 @@ public class Preferences { } public static synchronized Preferences getPreferences(Context context, boolean forceNew) { - if (mPreferences == null || forceNew) { - mPreferences = new Preferences(context); + if (sPreferences == null || forceNew) { + sPreferences = new Preferences(context); } - return mPreferences; + return sPreferences; } private Preferences(Context context) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java index 3df85cfc8..caa7842db 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java @@ -22,14 +22,14 @@ import android.content.Context; public class PgpGeneralMsgIdException extends Exception { static final long serialVersionUID = 0xf812773343L; - private final int msgId; + private final int mMessageId; - public PgpGeneralMsgIdException(int msgId) { - super("msg[" + msgId + "]"); - this.msgId = msgId; + public PgpGeneralMsgIdException(int messageId) { + super("msg[" + messageId + "]"); + mMessageId = messageId; } public PgpGeneralException getContextualized(Context context) { - return new PgpGeneralException(context.getString(msgId), this); + return new PgpGeneralException(context.getString(mMessageId), this); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index 5b7f9e4cc..4387f3d53 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -264,8 +264,8 @@ public class EncryptAsymmetricFragment extends Fragment { case RESULT_CODE_SECRET_KEYS: { if (resultCode == Activity.RESULT_OK) { - Uri uri_master_key = data.getData(); - setSignatureKeyId(Long.valueOf(uri_master_key.getLastPathSegment())); + Uri uriMasterKey = data.getData(); + setSignatureKeyId(Long.valueOf(uriMasterKey.getLastPathSegment())); } else { setSignatureKeyId(Id.key.none); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java index 04179cb80..c541e8a23 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java @@ -38,11 +38,11 @@ public class PreferencesActivity extends PreferenceActivity { public static final String ACTION_PREFS_ADV = "org.sufficientlysecure.keychain.ui.PREFS_ADV"; private PreferenceScreen mKeyServerPreference = null; - private static Preferences mPreferences; + private static Preferences sPreferences; @Override protected void onCreate(Bundle savedInstanceState) { - mPreferences = Preferences.getPreferences(this); + sPreferences = Preferences.getPreferences(this); super.onCreate(savedInstanceState); // final ActionBar actionBar = getSupportActionBar(); @@ -59,7 +59,7 @@ public class PreferencesActivity extends PreferenceActivity { (IntegerListPreference) findPreference(Constants.Pref.PASS_PHRASE_CACHE_TTL)); mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS); - String servers[] = mPreferences.getKeyServers(); + String servers[] = sPreferences.getKeyServers(); mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers, servers.length, servers.length)); mKeyServerPreference @@ -68,7 +68,7 @@ public class PreferencesActivity extends PreferenceActivity { Intent intent = new Intent(PreferencesActivity.this, PreferencesKeyServerActivity.class); intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS, - mPreferences.getKeyServers()); + sPreferences.getKeyServers()); startActivityForResult(intent, Id.request.key_server_preference); return false; } @@ -125,7 +125,7 @@ public class PreferencesActivity extends PreferenceActivity { } String servers[] = data .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS); - mPreferences.setKeyServers(servers); + sPreferences.setKeyServers(servers); mKeyServerPreference.setSummary(getResources().getQuantityString( R.plurals.n_key_servers, servers.length, servers.length)); break; @@ -163,7 +163,7 @@ public class PreferencesActivity extends PreferenceActivity { (IntegerListPreference) findPreference(Constants.Pref.PASS_PHRASE_CACHE_TTL)); mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS); - String servers[] = mPreferences.getKeyServers(); + String servers[] = sPreferences.getKeyServers(); mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers, servers.length, servers.length)); mKeyServerPreference @@ -172,7 +172,7 @@ public class PreferencesActivity extends PreferenceActivity { Intent intent = new Intent(getActivity(), PreferencesKeyServerActivity.class); intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS, - mPreferences.getKeyServers()); + sPreferences.getKeyServers()); startActivityForResult(intent, Id.request.key_server_preference); return false; } @@ -188,7 +188,7 @@ public class PreferencesActivity extends PreferenceActivity { } String servers[] = data .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS); - mPreferences.setKeyServers(servers); + sPreferences.setKeyServers(servers); mKeyServerPreference.setSummary(getResources().getQuantityString( R.plurals.n_key_servers, servers.length, servers.length)); break; @@ -256,14 +256,14 @@ public class PreferencesActivity extends PreferenceActivity { } private static void initializePassPassPhraceCacheTtl(final IntegerListPreference mPassphraseCacheTtl) { - mPassphraseCacheTtl.setValue("" + mPreferences.getPassPhraseCacheTtl()); + mPassphraseCacheTtl.setValue("" + sPreferences.getPassPhraseCacheTtl()); mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry()); mPassphraseCacheTtl .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { mPassphraseCacheTtl.setValue(newValue.toString()); mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry()); - mPreferences.setPassPhraseCacheTtl(Integer.parseInt(newValue.toString())); + sPreferences.setPassPhraseCacheTtl(Integer.parseInt(newValue.toString())); return false; } }); @@ -282,14 +282,14 @@ public class PreferencesActivity extends PreferenceActivity { } mEncryptionAlgorithm.setEntries(entries); mEncryptionAlgorithm.setEntryValues(values); - mEncryptionAlgorithm.setValue("" + mPreferences.getDefaultEncryptionAlgorithm()); + mEncryptionAlgorithm.setValue("" + sPreferences.getDefaultEncryptionAlgorithm()); mEncryptionAlgorithm.setSummary(mEncryptionAlgorithm.getEntry()); mEncryptionAlgorithm .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { mEncryptionAlgorithm.setValue(newValue.toString()); mEncryptionAlgorithm.setSummary(mEncryptionAlgorithm.getEntry()); - mPreferences.setDefaultEncryptionAlgorithm(Integer.parseInt(newValue + sPreferences.setDefaultEncryptionAlgorithm(Integer.parseInt(newValue .toString())); return false; } @@ -309,13 +309,13 @@ public class PreferencesActivity extends PreferenceActivity { } mHashAlgorithm.setEntries(entries); mHashAlgorithm.setEntryValues(values); - mHashAlgorithm.setValue("" + mPreferences.getDefaultHashAlgorithm()); + mHashAlgorithm.setValue("" + sPreferences.getDefaultHashAlgorithm()); mHashAlgorithm.setSummary(mHashAlgorithm.getEntry()); mHashAlgorithm.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { mHashAlgorithm.setValue(newValue.toString()); mHashAlgorithm.setSummary(mHashAlgorithm.getEntry()); - mPreferences.setDefaultHashAlgorithm(Integer.parseInt(newValue.toString())); + sPreferences.setDefaultHashAlgorithm(Integer.parseInt(newValue.toString())); return false; } }); @@ -326,14 +326,14 @@ public class PreferencesActivity extends PreferenceActivity { int[] valueIds, String[] entries, String[] values) { mMessageCompression.setEntries(entries); mMessageCompression.setEntryValues(values); - mMessageCompression.setValue("" + mPreferences.getDefaultMessageCompression()); + mMessageCompression.setValue("" + sPreferences.getDefaultMessageCompression()); mMessageCompression.setSummary(mMessageCompression.getEntry()); mMessageCompression .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { mMessageCompression.setValue(newValue.toString()); mMessageCompression.setSummary(mMessageCompression.getEntry()); - mPreferences.setDefaultMessageCompression(Integer.parseInt(newValue + sPreferences.setDefaultMessageCompression(Integer.parseInt(newValue .toString())); return false; } @@ -344,36 +344,36 @@ public class PreferencesActivity extends PreferenceActivity { (final IntegerListPreference mFileCompression, String[] entries, String[] values) { mFileCompression.setEntries(entries); mFileCompression.setEntryValues(values); - mFileCompression.setValue("" + mPreferences.getDefaultFileCompression()); + mFileCompression.setValue("" + sPreferences.getDefaultFileCompression()); mFileCompression.setSummary(mFileCompression.getEntry()); mFileCompression.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { mFileCompression.setValue(newValue.toString()); mFileCompression.setSummary(mFileCompression.getEntry()); - mPreferences.setDefaultFileCompression(Integer.parseInt(newValue.toString())); + sPreferences.setDefaultFileCompression(Integer.parseInt(newValue.toString())); return false; } }); } private static void initializeAsciiArmour(final CheckBoxPreference mAsciiArmour) { - mAsciiArmour.setChecked(mPreferences.getDefaultAsciiArmour()); + mAsciiArmour.setChecked(sPreferences.getDefaultAsciiArmour()); mAsciiArmour.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { mAsciiArmour.setChecked((Boolean) newValue); - mPreferences.setDefaultAsciiArmour((Boolean) newValue); + sPreferences.setDefaultAsciiArmour((Boolean) newValue); return false; } }); } private static void initializeForceV3Signatures(final CheckBoxPreference mForceV3Signatures) { - mForceV3Signatures.setChecked(mPreferences.getForceV3Signatures()); + mForceV3Signatures.setChecked(sPreferences.getForceV3Signatures()); mForceV3Signatures .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { mForceV3Signatures.setChecked((Boolean) newValue); - mPreferences.setForceV3Signatures((Boolean) newValue); + sPreferences.setForceV3Signatures((Boolean) newValue); return false; } }); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 8cb321109..f322ea980 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -44,12 +44,12 @@ public class ImportKeysAdapter extends ArrayAdapter { protected List mData; static class ViewHolder { - private TextView mainUserId; - private TextView mainUserIdRest; - private TextView keyId; - private TextView fingerprint; - private TextView algorithm; - private TextView status; + public TextView mainUserId; + public TextView mainUserIdRest; + public TextView keyId; + public TextView fingerprint; + public TextView algorithm; + public TextView status; } public ImportKeysAdapter(Activity activity) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java index 9b20effc2..4fccadf30 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java @@ -249,7 +249,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable { /** * Based on OpenPGP Message Format */ - private final static SparseArray ALGORITHM_IDS = new SparseArray() {{ + private static final SparseArray ALGORITHM_IDS = new SparseArray() {{ put(-1, "unknown"); // TODO: with resources put(0, "unencrypted"); put(PGPPublicKey.RSA_GENERAL, "RSA"); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java index 4a3796f01..fd864eb09 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java @@ -30,9 +30,9 @@ public class PagerTabStripAdapter extends FragmentPagerAdapter { private final ArrayList mTabs = new ArrayList(); static final class TabInfo { - private final Class clss; - private final Bundle args; - private final String title; + public final Class clss; + public final Bundle args; + public final String title; TabInfo(Class clss, Bundle args, String title) { this.clss = clss; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java index 6dbea61dc..9ddfa90be 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java @@ -36,8 +36,8 @@ public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar. private final ArrayList mTabs = new ArrayList(); static final class TabInfo { - private final Class clss; - private final Bundle args; + public final Class clss; + public final Bundle args; TabInfo(Class clss, Bundle args) { this.clss = clss; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java index 21a150606..fcaa6a940 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java @@ -37,7 +37,7 @@ public class ViewKeyUserIdsAdapter extends CursorAdapter { private int mIndexUserId, mIndexRank; - final private ArrayList mCheckStates; + private final ArrayList mCheckStates; public ViewKeyUserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes) { super(context, c, flags); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index 60dea2a41..02ebde1c8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -51,12 +51,12 @@ public class DeleteKeyDialogFragment extends DialogFragment { public static final int MESSAGE_OKAY = 1; public static final int MESSAGE_ERROR = 0; - private boolean isSingleSelection = false; + private boolean mIsSingleSelection = false; - private TextView mainMessage; - private CheckBox checkDeleteSecret; - private LinearLayout deleteSecretKeyView; - private View inflateView; + private TextView mMainMessage; + private CheckBox mCheckDeleteSecret; + private LinearLayout mDeleteSecretKeyView; + private View mInflateView; private Messenger mMessenger; @@ -90,12 +90,12 @@ public class DeleteKeyDialogFragment extends DialogFragment { //Setup custom View to display in AlertDialog LayoutInflater inflater = activity.getLayoutInflater(); - inflateView = inflater.inflate(R.layout.view_key_delete_fragment, null); - builder.setView(inflateView); + mInflateView = inflater.inflate(R.layout.view_key_delete_fragment, null); + builder.setView(mInflateView); - deleteSecretKeyView = (LinearLayout) inflateView.findViewById(R.id.deleteSecretKeyView); - mainMessage = (TextView) inflateView.findViewById(R.id.mainMessage); - checkDeleteSecret = (CheckBox) inflateView.findViewById(R.id.checkDeleteSecret); + mDeleteSecretKeyView = (LinearLayout) mInflateView.findViewById(R.id.deleteSecretKeyView); + mMainMessage = (TextView) mInflateView.findViewById(R.id.mainMessage); + mCheckDeleteSecret = (CheckBox) mInflateView.findViewById(R.id.checkDeleteSecret); builder.setTitle(R.string.warning); @@ -103,7 +103,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { if (keyRingRowIds.length == 1) { Uri dataUri; ArrayList publicKeyRings; //Any one will do - isSingleSelection = true; + mIsSingleSelection = true; long selectedRow = keyRingRowIds[0]; long keyType; @@ -119,16 +119,16 @@ public class DeleteKeyDialogFragment extends DialogFragment { } String userId = ProviderHelper.getUserId(activity, dataUri); - //Hide the Checkbox and TextView since this is a single selection,user will be notified thru message - deleteSecretKeyView.setVisibility(View.GONE); - //Set message depending on which key it is. - mainMessage.setText(getString(keyType == Id.type.secret_key ? R.string.secret_key_deletion_confirmation - : R.string.public_key_deletetion_confirmation, userId)); - - + // Hide the Checkbox and TextView since this is a single selection, + // user will be notified thru message + mDeleteSecretKeyView.setVisibility(View.GONE); + // Set message depending on which key it is. + mMainMessage.setText(getString(keyType == Id.type.secret_key ? + R.string.secret_key_deletion_confirmation : + R.string.public_key_deletetion_confirmation, userId)); } else { - deleteSecretKeyView.setVisibility(View.VISIBLE); - mainMessage.setText(R.string.key_deletion_confirmation_multi); + mDeleteSecretKeyView.setVisibility(View.VISIBLE); + mMainMessage.setText(R.string.key_deletion_confirmation_multi); } @@ -171,8 +171,9 @@ public class DeleteKeyDialogFragment extends DialogFragment { if (keyType == KeychainContract.KeyTypes.SECRET) { - if (checkDeleteSecret.isChecked() || isSingleSelection) { - ProviderHelper.deleteUnifiedKeyRing(activity, String.valueOf(masterKeyId), true); + if (mCheckDeleteSecret.isChecked() || mIsSingleSelection) { + ProviderHelper.deleteUnifiedKeyRing(activity, + String.valueOf(masterKeyId), true); } } else { ProviderHelper.deleteUnifiedKeyRing(activity, String.valueOf(masterKeyId), false); @@ -180,8 +181,10 @@ public class DeleteKeyDialogFragment extends DialogFragment { } //Check if the selected rows have actually been deleted - cursor = activity.getContentResolver().query(queryUri, projection, selection, null, null); - if (cursor == null || cursor.getCount() == 0 || !checkDeleteSecret.isChecked()) { + cursor = activity.getContentResolver().query( + queryUri, projection, selection, null, null); + if (cursor == null || cursor.getCount() == 0 || + !mCheckDeleteSecret.isChecked()) { isSuccessfullyDeleted = true; } } finally { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 272f43915..150f6e221 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -61,7 +61,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor private Choice mNewKeyAlgorithmChoice; private int mNewKeySize; - private boolean oldItemDeleted = false; + private boolean mOldItemDeleted = false; private ArrayList mDeletedIDs = new ArrayList(); private ArrayList mDeletedKeys = new ArrayList(); private boolean mCanEdit = true; @@ -138,13 +138,13 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor * {@inheritDoc} */ public void onDeleted(Editor editor, boolean wasNewItem) { - oldItemDeleted |= !wasNewItem; - if (oldItemDeleted) { - if (mType == Id.type.user_id) - mDeletedIDs.add(((UserIdEditor)editor).getOriginalID()); - else if (mType == Id.type.key) - mDeletedKeys.add(((KeyEditor)editor).getValue()); - + mOldItemDeleted |= !wasNewItem; + if (mOldItemDeleted) { + if (mType == Id.type.user_id) { + mDeletedIDs.add(((UserIdEditor) editor).getOriginalID()); + } else if (mType == Id.type.key) { + mDeletedKeys.add(((KeyEditor) editor).getValue()); + } } this.updateEditorsVisible(); if (mEditorListener != null) { @@ -167,7 +167,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor public boolean needsSaving() { //check each view for needs saving, take account of deleted items - boolean ret = oldItemDeleted; + boolean ret = mOldItemDeleted; for (int i = 0; i < mEditors.getChildCount(); ++i) { Editor editor = (Editor) mEditors.getChildAt(i); ret |= editor.needsSaving(); -- cgit v1.2.3 From 82e5d14fb1b14906a59a6b1bd61faec74514efc0 Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Wed, 2 Apr 2014 01:56:58 +0200 Subject: Rearrange too long lines --- .../keychain/pgp/PgpDecryptVerify.java | 3 +- .../sufficientlysecure/keychain/pgp/PgpHelper.java | 6 +- .../keychain/pgp/PgpImportExport.java | 3 +- .../keychain/pgp/PgpKeyOperation.java | 96 +++++++++++++--------- .../sufficientlysecure/keychain/pgp/PgpToX509.java | 21 ++--- .../keychain/provider/KeychainContract.java | 6 +- .../keychain/provider/ProviderHelper.java | 16 ++-- .../keychain/remote/OpenPgpService.java | 15 ++-- .../keychain/remote/RemoteService.java | 3 +- .../remote/ui/AccountSettingsFragment.java | 3 +- .../keychain/service/KeychainIntentService.java | 20 +++-- .../keychain/ui/CertifyKeyActivity.java | 3 +- .../keychain/ui/DecryptActivity.java | 9 +- .../keychain/ui/DecryptFileFragment.java | 3 +- .../keychain/ui/DecryptMessageFragment.java | 3 +- .../keychain/ui/EditKeyActivity.java | 9 +- .../keychain/ui/EncryptActivity.java | 21 +++-- .../keychain/ui/EncryptFileFragment.java | 11 ++- .../keychain/ui/EncryptMessageFragment.java | 11 ++- .../keychain/ui/ImportKeysActivity.java | 8 +- .../keychain/ui/KeyListActivity.java | 6 +- .../keychain/ui/KeyListFragment.java | 9 +- .../keychain/ui/ViewKeyActivity.java | 3 +- .../keychain/ui/adapter/ImportKeysListEntry.java | 4 +- .../ui/dialog/DeleteKeyDialogFragment.java | 10 ++- .../ui/dialog/ShareQrCodeDialogFragment.java | 2 +- .../keychain/ui/widget/KeyEditor.java | 23 ++++-- .../keychain/util/HkpKeyServer.java | 46 ++++++----- 28 files changed, 228 insertions(+), 145 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 003db632d..90b48e017 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -684,7 +684,8 @@ public class PgpDecryptVerify { } private static boolean verifyPrimaryKeyBinding(PGPSignatureSubpacketVector pkts, - PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { + PGPPublicKey masterPublicKey, + PGPPublicKey signingPublicKey) { boolean validPrimaryKeyBinding = false; JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java index 7a3338c7c..7a2cb0d96 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java @@ -51,9 +51,9 @@ public class PgpHelper { ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL); public static final Pattern PGP_CLEARTEXT_SIGNATURE = Pattern - .compile( - ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", - Pattern.DOTALL); + .compile(".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----" + + "BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", + Pattern.DOTALL); public static final Pattern PGP_PUBLIC_KEY = Pattern.compile( ".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*", diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index de405d132..69c2c8bf2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -168,7 +168,8 @@ public class PgpImportExport { return returnData; } - public Bundle exportKeyRings(ArrayList publicKeyRingMasterIds, ArrayList secretKeyRingMasterIds, + public Bundle exportKeyRings(ArrayList publicKeyRingMasterIds, + ArrayList secretKeyRingMasterIds, OutputStream outStream) throws PgpGeneralException, PGPException, IOException { Bundle returnData = new Bundle(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index d4fba68ff..ceccf7a70 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -196,8 +196,8 @@ public class PgpKeyOperation { } public PGPSecretKeyRing changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassPhrase, - String newPassPhrase) throws IOException, PGPException, - NoSuchProviderException { + String newPassPhrase) + throws IOException, PGPException, NoSuchProviderException { updateProgress(R.string.progress_building_key, 0, 100); if (oldPassPhrase == null) { @@ -270,13 +270,16 @@ public class PgpKeyOperation { GregorianCalendar expiryDate = keysExpiryDates.get(0); //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c //here we purposefully ignore partial days in each date - long type has no fractional part! - long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); - if (numDays <= 0) + long numDays = (expiryDate.getTimeInMillis() / 86400000) - + (creationDate.getTimeInMillis() / 86400000); + if (numDays <= 0) { throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation); + } hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); } else { - hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, - //this happens anyway + hashedPacketsGen.setKeyExpirationTime(false, 0); + // do this explicitly, although since we're rebuilding, + // this happens anyway } updateProgress(R.string.progress_building_master_key, 30, 100); @@ -342,15 +345,16 @@ public class PgpKeyOperation { GregorianCalendar expiryDate = keysExpiryDates.get(i); //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c //here we purposefully ignore partial days in each date - long type has no fractional part! - long numDays = - (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); + long numDays = (expiryDate.getTimeInMillis() / 86400000) - + (creationDate.getTimeInMillis() / 86400000); if (numDays <= 0) { throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation); } hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); } else { - hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, - //this happens anyway + hashedPacketsGen.setKeyExpirationTime(false, 0); + // do this explicitly, although since we're rebuilding, + // this happens anyway } keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate()); @@ -447,22 +451,28 @@ public class PgpKeyOperation { GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(0); //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c //here we purposefully ignore partial days in each date - long type has no fractional part! - long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); - if (numDays <= 0) + long numDays = (expiryDate.getTimeInMillis() / 86400000) - + (creationDate.getTimeInMillis() / 86400000); + if (numDays <= 0) { throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation); + } hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); } else { - hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, - //this happens anyway + hashedPacketsGen.setKeyExpirationTime(false, 0); + // do this explicitly, although since we're rebuilding, + // this happens anyway } - if (saveParcel.primaryIDChanged || !saveParcel.originalIDs.get(0).equals(saveParcel.userIDs.get(0))) { + if (saveParcel.primaryIDChanged || + !saveParcel.originalIDs.get(0).equals(saveParcel.userIDs.get(0))) { anyIDChanged = true; ArrayList> sigList = new ArrayList>(); for (String userId : saveParcel.userIDs) { String origID = saveParcel.originalIDs.get(userIDIndex); - if ((origID.equals(userId) && !saveParcel.newIDs[userIDIndex]) && !userId.equals(saveParcel.originalPrimaryID) && userIDIndex != 0) { - Iterator origSigs = masterPublicKey.getSignaturesForID(origID); //TODO: make sure this iterator only has signatures we are interested in + if (origID.equals(userId) && !saveParcel.newIDs[userIDIndex] && + !userId.equals(saveParcel.originalPrimaryID) && userIDIndex != 0) { + Iterator origSigs = masterPublicKey.getSignaturesForID(origID); + // TODO: make sure this iterator only has signatures we are interested in while (origSigs.hasNext()) { PGPSignature origSig = origSigs.next(); sigList.add(new Pair(origID, origSig)); @@ -487,7 +497,8 @@ public class PgpKeyOperation { userIDIndex++; } for (Pair toAdd : sigList) { - masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, toAdd.first, toAdd.second); + masterPublicKey = + PGPPublicKey.addCertification(masterPublicKey, toAdd.first, toAdd.second); } } else { for (String userId : saveParcel.userIDs) { @@ -508,7 +519,8 @@ public class PgpKeyOperation { if (!saveParcel.newIDs[userIDIndex]) { masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID); } - masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); + masterPublicKey = + PGPPublicKey.addCertification(masterPublicKey, userId, certification); } userIDIndex++; } @@ -520,7 +532,8 @@ public class PgpKeyOperation { for (String userId : saveParcel.userIDs) { String origID = saveParcel.originalIDs.get(userIDIndex); if (!(origID.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged)) { - Iterator sigs = masterPublicKey.getSignaturesForID(userId); //TODO: make sure this iterator only has signatures we are interested in + Iterator sigs = masterPublicKey.getSignaturesForID(userId); + // TODO: make sure this iterator only has signatures we are interested in while (sigs.hasNext()) { PGPSignature sig = sigs.next(); sigList.add(new Pair(userId, sig)); @@ -605,23 +618,27 @@ public class PgpKeyOperation { GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC")); creationDate.setTime(subPublicKey.getCreationTime()); GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(i); - //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c - //here we purposefully ignore partial days in each date - long type has no fractional part! - long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); - if (numDays <= 0) + // note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c + // here we purposefully ignore partial days in each date - long type has + // no fractional part! + long numDays = (expiryDate.getTimeInMillis() / 86400000) - + (creationDate.getTimeInMillis() / 86400000); + if (numDays <= 0) { throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation); + } hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); } else { - hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, - //this happens anyway + hashedPacketsGen.setKeyExpirationTime(false, 0); + // do this explicitly, although since we're rebuilding, + // this happens anyway } keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate()); - //certifications will be discarded if the key is changed, because I think, for a start, - //they will be invalid. Binding certs are regenerated anyway, and other certs which - //need to be kept are on IDs and attributes - //TODO: don't let revoked keys be edited, other than removed - changing one would result in the - //revocation being wrong? + // certifications will be discarded if the key is changed, because I think, for a start, + // they will be invalid. Binding certs are regenerated anyway, and other certs which + // need to be kept are on IDs and attributes + // TODO: don't let revoked keys be edited, other than removed - changing one would + // result in the revocation being wrong? } } @@ -660,8 +677,10 @@ public class PgpKeyOperation { Log.d(Constants.TAG, " ------- in private key -------"); for(String uid : new IterableIterator(secretKeyRing.getPublicKey().getUserIDs())) { - for(PGPSignature sig : new IterableIterator(secretKeyRing.getPublicKey().getSignaturesForID(uid))) { - Log.d(Constants.TAG, "sig: " + PgpKeyHelper.convertKeyIdToHex(sig.getKeyID()) + " for " + uid); + for(PGPSignature sig : new IterableIterator( + secretKeyRing.getPublicKey().getSignaturesForID(uid))) { + Log.d(Constants.TAG, "sig: " + + PgpKeyHelper.convertKeyIdToHex(sig.getKeyID()) + " for " + uid); } } @@ -669,8 +688,10 @@ public class PgpKeyOperation { Log.d(Constants.TAG, " ------- in public key -------"); for(String uid : new IterableIterator(publicKeyRing.getPublicKey().getUserIDs())) { - for(PGPSignature sig : new IterableIterator(publicKeyRing.getPublicKey().getSignaturesForID(uid))) { - Log.d(Constants.TAG, "sig: " + PgpKeyHelper.convertKeyIdToHex(sig.getKeyID()) + " for " + uid); + for(PGPSignature sig : new IterableIterator( + publicKeyRing.getPublicKey().getSignaturesForID(uid))) { + Log.d(Constants.TAG, "sig: " + + PgpKeyHelper.convertKeyIdToHex(sig.getKeyID()) + " for " + uid); } } @@ -689,9 +710,10 @@ public class PgpKeyOperation { * @param passphrase Passphrase of the secret key * @return A keyring with added certifications */ - public PGPPublicKey certifyKey(PGPSecretKey certificationKey, PGPPublicKey publicKey, List userIds, String passphrase) + public PGPPublicKey certifyKey(PGPSecretKey certificationKey, PGPPublicKey publicKey, + List userIds, String passphrase) throws PgpGeneralMsgIdException, NoSuchAlgorithmException, NoSuchProviderException, - PGPException, SignatureException { + PGPException, SignatureException { // create a signatureGenerator from the supplied masterKeyId and passphrase PGPSignatureGenerator signatureGenerator; { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java index fa54afa86..5bb1665b6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java @@ -83,9 +83,10 @@ public class PgpToX509 { * @throws Exception * @author Bruno Harbulot */ - public static X509Certificate createSelfSignedCert(PublicKey pubKey, PrivateKey privKey, - X509Name subject, Date startDate, Date endDate, String subjAltNameURI) - throws InvalidKeyException, IllegalStateException, NoSuchAlgorithmException, + public static X509Certificate createSelfSignedCert( + PublicKey pubKey, PrivateKey privKey, X509Name subject, Date startDate, Date endDate, + String subjAltNameURI) + throws InvalidKeyException, IllegalStateException, NoSuchAlgorithmException, SignatureException, CertificateException, NoSuchProviderException { X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator(); @@ -182,10 +183,10 @@ public class PgpToX509 { /** * Creates a self-signed certificate from a PGP Secret Key. * - * @param pgpSecKey PGP Secret Key (from which one can extract the public and private keys and other - * attributes). - * @param pgpPrivKey PGP Private Key corresponding to the Secret Key (password callbacks should be done - * before calling this method) + * @param pgpSecKey PGP Secret Key (from which one can extract the public and private + * keys and other attributes). + * @param pgpPrivKey PGP Private Key corresponding to the Secret Key (password callbacks + * should be done before calling this method) * @param subjAltNameURI optional URI to embed in the subject alternative-name * @return self-signed certificate * @throws PGPException @@ -196,9 +197,9 @@ public class PgpToX509 { * @throws CertificateException * @author Bruno Harbulot */ - public static X509Certificate createSelfSignedCert(PGPSecretKey pgpSecKey, - PGPPrivateKey pgpPrivKey, String subjAltNameURI) throws PGPException, - NoSuchProviderException, InvalidKeyException, NoSuchAlgorithmException, + public static X509Certificate createSelfSignedCert( + PGPSecretKey pgpSecKey, PGPPrivateKey pgpPrivKey, String subjAltNameURI) + throws PGPException, NoSuchProviderException, InvalidKeyException, NoSuchAlgorithmException, SignatureException, CertificateException { // get public key from secret key PGPPublicKey pgpPubKey = pgpSecKey.getPublicKey(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index e7b31bf65..1a9b67261 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -283,12 +283,14 @@ public class KeychainContract { /** * Use if multiple items get returned */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api_app.accounts"; + public static final String CONTENT_TYPE = + "vnd.android.cursor.dir/vnd.thialfihar.apg.api_app.accounts"; /** * Use if a single item is returned */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_app.account"; + public static final String CONTENT_ITEM_TYPE = + "vnd.android.cursor.item/vnd.thialfihar.apg.api_app.account"; public static Uri buildBaseUri(String packageName) { return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS) diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index c88e3e22f..6882b6925 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -296,8 +296,8 @@ public class ProviderHelper { /** * Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing */ - private static ContentProviderOperation buildPublicKeyOperations(Context context, - long keyRingRowId, PGPPublicKey key, int rank) throws IOException { + private static ContentProviderOperation buildPublicKeyOperations( + Context context, long keyRingRowId, PGPPublicKey key, int rank) throws IOException { ContentValues values = new ContentValues(); values.put(Keys.KEY_ID, key.getKeyID()); values.put(Keys.IS_MASTER_KEY, key.isMasterKey()); @@ -324,8 +324,8 @@ public class ProviderHelper { /** * Build ContentProviderOperation to add PublicUserIds to database corresponding to a keyRing */ - private static ContentProviderOperation buildPublicUserIdOperations(Context context, - long keyRingRowId, String userId, int rank) { + private static ContentProviderOperation buildPublicUserIdOperations( + Context context, long keyRingRowId, String userId, int rank) { ContentValues values = new ContentValues(); values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId); values.put(UserIds.USER_ID, userId); @@ -339,8 +339,8 @@ public class ProviderHelper { /** * Build ContentProviderOperation to add PGPSecretKey to database corresponding to a keyRing */ - private static ContentProviderOperation buildSecretKeyOperations(Context context, - long keyRingRowId, PGPSecretKey key, int rank) throws IOException { + private static ContentProviderOperation buildSecretKeyOperations( + Context context, long keyRingRowId, PGPSecretKey key, int rank) throws IOException { ContentValues values = new ContentValues(); boolean hasPrivate = true; @@ -376,8 +376,8 @@ public class ProviderHelper { /** * Build ContentProviderOperation to add SecretUserIds to database corresponding to a keyRing */ - private static ContentProviderOperation buildSecretUserIdOperations(Context context, - long keyRingRowId, String userId, int rank) { + private static ContentProviderOperation buildSecretUserIdOperations( + Context context, long keyRingRowId, String userId, int rank) { ContentValues values = new ContentValues(); values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId); values.put(UserIds.USER_ID, userId); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index b00c012b8..18bb92552 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -188,7 +188,8 @@ public class OpenPgpService extends RemoteService { } private Intent encryptAndSignImpl(Intent data, ParcelFileDescriptor input, - ParcelFileDescriptor output, AccountSettings accSettings, boolean sign) { + ParcelFileDescriptor output, AccountSettings accSettings, + boolean sign) { try { boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); @@ -292,7 +293,8 @@ public class OpenPgpService extends RemoteService { PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os); builder.allowSymmetricDecryption(false) // no support for symmetric encryption - .allowedKeyIds(allowedKeyIds) // allow only private keys associated with accounts of this app + .allowedKeyIds(allowedKeyIds) // allow only private keys associated with + // accounts of this app .passphrase(passphrase); // TODO: currently does not support binary signed-only content @@ -300,9 +302,11 @@ public class OpenPgpService extends RemoteService { if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, decryptVerifyResult.getKeyIdPassphraseNeeded()); + Intent passphraseBundle = + getPassphraseBundleIntent(data, decryptVerifyResult.getKeyIdPassphraseNeeded()); return passphraseBundle; - } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { + } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == + decryptVerifyResult.getStatus()) { throw new PgpGeneralException("Decryption of symmetric content not supported by API!"); } @@ -455,7 +459,8 @@ public class OpenPgpService extends RemoteService { } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) { String currentPkg = getCurrentCallingPackage(); Set allowedKeyIds = - ProviderHelper.getAllKeyIdsForApp(mContext, KeychainContract.ApiAccounts.buildBaseUri(currentPkg)); + ProviderHelper.getAllKeyIdsForApp(mContext, + KeychainContract.ApiAccounts.buildBaseUri(currentPkg)); return decryptAndVerifyImpl(data, input, output, allowedKeyIds); } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) { return getKeyImpl(data); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java index 3e72eec17..16a800022 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java @@ -243,7 +243,8 @@ public abstract class RemoteService extends Service { return true; } else { throw new WrongPackageSignatureException( - "PACKAGE NOT ALLOWED! Signature wrong! (Signature not equals signature from database)"); + "PACKAGE NOT ALLOWED! Signature wrong! (Signature not " + + "equals signature from database)"); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java index eec54b4cc..150cf2897 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java @@ -69,7 +69,8 @@ public class AccountSettingsFragment extends Fragment implements this.mAccSettings = accountSettings; mAccNameView.setText(accountSettings.getAccountName()); - Uri keyUri = KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(accountSettings.getKeyId())); + Uri keyUri = KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri( + String.valueOf(accountSettings.getKeyId())); mSelectKeyFragment.selectKey(keyUri); mEncryptionAlgorithm.setSelection(mEncryptionAdapter.getPosition(accountSettings .getEncryptionAlgorithm())); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 14beae40c..487da80ca 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -485,10 +485,13 @@ public class KeychainIntentService extends IntentService ProviderHelper.saveKeyRing(this, keyRing); setProgress(R.string.progress_done, 100, 100); } else { - PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 90, 100)); - PGPSecretKeyRing privkey = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, masterKeyId); - PGPPublicKeyRing pubkey = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, masterKeyId); - PgpKeyOperation.Pair pair = + PgpKeyOperation keyOperations = + new PgpKeyOperation(new ProgressScaler(this, 0, 90, 100)); + PGPSecretKeyRing privkey = + ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, masterKeyId); + PGPPublicKeyRing pubkey = + ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, masterKeyId); + PgpKeyOperation.Pair pair = keyOperations.buildSecretKey(privkey, pubkey, saveParams); setProgress(R.string.progress_saving_key_ring, 90, 100); ProviderHelper.saveKeyRing(this, pair.first); @@ -745,11 +748,14 @@ public class KeychainIntentService extends IntentService // verify downloaded key by comparing fingerprints if (entry.getFingerPrintHex() != null) { - String downloadedKeyFp = PgpKeyHelper.convertFingerprintToHex(downloadedKey.getPublicKey().getFingerprint()); + String downloadedKeyFp = PgpKeyHelper.convertFingerprintToHex( + downloadedKey.getPublicKey().getFingerprint()); if (downloadedKeyFp.equals(entry.getFingerPrintHex())) { - Log.d(Constants.TAG, "fingerprint of downloaded key is the same as the requested fingerprint!"); + Log.d(Constants.TAG, "fingerprint of downloaded key is the same as " + + "the requested fingerprint!"); } else { - throw new PgpGeneralException("fingerprint of downloaded key is NOT the same as the requested fingerprint!"); + throw new PgpGeneralException("fingerprint of downloaded key is " + + "NOT the same as the requested fingerprint!"); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index d041bc35e..e7da531e1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -212,7 +212,8 @@ public class CertifyKeyActivity extends ActionBarActivity implements fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri); } String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); - ((TextView) findViewById(R.id.fingerprint)).setText(PgpKeyHelper.colorizeFingerprint(fingerprint)); + ((TextView) findViewById(R.id.fingerprint)) + .setText(PgpKeyHelper.colorizeFingerprint(fingerprint)); } break; case LOADER_ID_USER_IDS: diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 046d80b72..8533e9072 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -77,8 +77,10 @@ public class DecryptActivity extends DrawerActivity { // Handle intent actions, maybe changes the bundles handleActions(getIntent()); - mTabsAdapter.addTab(DecryptMessageFragment.class, mMessageFragmentBundle, getString(R.string.label_message)); - mTabsAdapter.addTab(DecryptFileFragment.class, mFileFragmentBundle, getString(R.string.label_file)); + mTabsAdapter.addTab(DecryptMessageFragment.class, + mMessageFragmentBundle, getString(R.string.label_message)); + mTabsAdapter.addTab(DecryptFileFragment.class, + mFileFragmentBundle, getString(R.string.label_file)); mViewPager.setCurrentItem(mSwitchToTab); } @@ -164,7 +166,8 @@ public class DecryptActivity extends DrawerActivity { mSwitchToTab = PAGER_TAB_FILE; } else { Log.e(Constants.TAG, - "Direct binary data without actual file in filesystem is not supported. Please use the Remote Service API!"); + "Direct binary data without actual file in filesystem is not supported. " + + "Please use the Remote Service API!"); Toast.makeText(this, R.string.error_only_files_are_supported, Toast.LENGTH_LONG) .show(); // end activity diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index 67cf8d3e3..492c0cf29 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -200,7 +200,8 @@ public class DecryptFileFragment extends DecryptFragment { if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded()); - } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { + } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == + decryptVerifyResult.getStatus()) { showPassphraseDialog(Id.key.symmetric); } else { AppMsg.makeText(getActivity(), R.string.decryption_successful, diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java index c7a56449b..2169bbd77 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java @@ -154,7 +154,8 @@ public class DecryptMessageFragment extends DecryptFragment { if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded()); - } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { + } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == + decryptVerifyResult.getStatus()) { showPassphraseDialog(Id.key.symmetric); } else { AppMsg.makeText(getActivity(), R.string.decryption_successful, diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 8ef4631dc..a8b3e29ed 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -125,7 +125,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public void somethingChanged() { ActivityCompat.invalidateOptionsMenu(this); - //Toast.makeText(this, "Needs saving: " + Boolean.toString(mNeedsSaving) + "(" + Boolean.toString(mUserIdsView.needsSaving()) + ", " + Boolean.toString(mKeysView.needsSaving()) + ")", Toast.LENGTH_LONG).show(); } public void onDeleted(Editor e, boolean wasNewItem) { @@ -329,7 +328,9 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: - cancelClicked(); //TODO: why isn't this triggered on my tablet - one of many ui problems I've had with this device. A code compatibility issue or a Samsung fail? + cancelClicked(); + // TODO: why isn't this triggered on my tablet - one of many ui problems + // I've had with this device. A code compatibility issue or a Samsung fail? return true; case R.id.menu_key_edit_cancel: cancelClicked(); @@ -340,8 +341,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } else { long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri); long[] ids = new long[] {masterKeyId}; - mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC, - null); + mExportHelper.showExportKeysDialog( + ids, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC, null); return true; } return true; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index db35b7c28..a03c7d797 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -155,12 +155,16 @@ public class EncryptActivity extends DrawerActivity implements // Handle intent actions handleActions(getIntent()); - mTabsAdapterMode.addTab(EncryptAsymmetricFragment.class, mAsymmetricFragmentBundle, getString(R.string.label_asymmetric)); - mTabsAdapterMode.addTab(EncryptSymmetricFragment.class, mSymmetricFragmentBundle, getString(R.string.label_symmetric)); + mTabsAdapterMode.addTab(EncryptAsymmetricFragment.class, + mAsymmetricFragmentBundle, getString(R.string.label_asymmetric)); + mTabsAdapterMode.addTab(EncryptSymmetricFragment.class, + mSymmetricFragmentBundle, getString(R.string.label_symmetric)); mViewPagerMode.setCurrentItem(mSwitchToMode); - mTabsAdapterContent.addTab(EncryptMessageFragment.class, mMessageFragmentBundle, getString(R.string.label_message)); - mTabsAdapterContent.addTab(EncryptFileFragment.class, mFileFragmentBundle, getString(R.string.label_file)); + mTabsAdapterContent.addTab(EncryptMessageFragment.class, + mMessageFragmentBundle, getString(R.string.label_message)); + mTabsAdapterContent.addTab(EncryptFileFragment.class, + mFileFragmentBundle, getString(R.string.label_file)); mViewPagerContent.setCurrentItem(mSwitchToContent); } @@ -212,8 +216,10 @@ public class EncryptActivity extends DrawerActivity implements long[] encryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS); // preselect keys given by intent - mAsymmetricFragmentBundle.putLongArray(EncryptAsymmetricFragment.ARG_ENCRYPTION_KEY_IDS, encryptionKeyIds); - mAsymmetricFragmentBundle.putLong(EncryptAsymmetricFragment.ARG_SIGNATURE_KEY_ID, signatureKeyId); + mAsymmetricFragmentBundle.putLongArray(EncryptAsymmetricFragment.ARG_ENCRYPTION_KEY_IDS, + encryptionKeyIds); + mAsymmetricFragmentBundle.putLong(EncryptAsymmetricFragment.ARG_SIGNATURE_KEY_ID, + signatureKeyId); mSwitchToMode = PAGER_MODE_ASYMMETRIC; /** @@ -234,7 +240,8 @@ public class EncryptActivity extends DrawerActivity implements mSwitchToContent = PAGER_CONTENT_FILE; } else { Log.e(Constants.TAG, - "Direct binary data without actual file in filesystem is not supported by Intents. Please use the Remote Service API!"); + "Direct binary data without actual file in filesystem is not supported " + + "by Intents. Please use the Remote Service API!"); Toast.makeText(this, R.string.error_only_files_are_supported, Toast.LENGTH_LONG) .show(); // end activity diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java index cee7dae87..c8ea6ffb7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java @@ -253,8 +253,9 @@ public class EncryptFileFragment extends Fragment { return; } - if (mEncryptInterface.getSignatureKey() != 0 - && PassphraseCacheService.getCachedPassphrase(getActivity(), mEncryptInterface.getSignatureKey()) == null) { + if (mEncryptInterface.getSignatureKey() != 0 && + PassphraseCacheService.getCachedPassphrase(getActivity(), + mEncryptInterface.getSignatureKey()) == null) { showPassphraseDialog(); return; @@ -283,8 +284,10 @@ public class EncryptFileFragment extends Fragment { } data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase); } else { - data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID, mEncryptInterface.getSignatureKey()); - data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptInterface.getEncryptionKeys()); + data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID, + mEncryptInterface.getSignatureKey()); + data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, + mEncryptInterface.getEncryptionKeys()); } Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java index f2187dac3..4522acf4e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java @@ -150,8 +150,9 @@ public class EncryptMessageFragment extends Fragment { return; } - if (mEncryptInterface.getSignatureKey() != 0 - && PassphraseCacheService.getCachedPassphrase(getActivity(), mEncryptInterface.getSignatureKey()) == null) { + if (mEncryptInterface.getSignatureKey() != 0 && + PassphraseCacheService.getCachedPassphrase(getActivity(), + mEncryptInterface.getSignatureKey()) == null) { showPassphraseDialog(toClipboard); return; @@ -182,8 +183,10 @@ public class EncryptMessageFragment extends Fragment { } data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase); } else { - data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID, mEncryptInterface.getSignatureKey()); - data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptInterface.getEncryptionKeys()); + data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID, + mEncryptInterface.getSignatureKey()); + data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, + mEncryptInterface.getEncryptionKeys()); boolean signOnly = (mEncryptInterface.getEncryptionKeys() == null || mEncryptInterface.getEncryptionKeys().length == 0); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index b73510e38..b09fa4a4d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -168,7 +168,8 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa } } else { Log.e(Constants.TAG, - "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query', 'key_id', or 'fingerprint' extra!"); + "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query', 'key_id', or " + + "'fingerprint' extra!"); return; } @@ -233,7 +234,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa * onNavigationItemSelected() should check whether the Fragment is already in existence * inside your Activity." *

- * from http://stackoverflow.com/questions/10983396/fragment-oncreateview-and-onactivitycreated-called-twice/14295474#14295474 + * from http://bit.ly/1dBYThO *

* In our case, if we start ImportKeysActivity with parameters to directly search using a fingerprint, * the fragment would be loaded twice resulting in the query being empty after the second load. @@ -337,7 +338,8 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa // } else { // status.putString( // EXTRA_ERROR, - // "Scanned fingerprint does NOT match the fingerprint of the received key. You shouldnt trust this key."); + // "Scanned fingerprint does NOT match the fingerprint of the received key. " + + // "You shouldnt trust this key."); // } // } // } catch (QueryException e) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java index 27d3bbbb0..1f884d7e3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java @@ -66,11 +66,13 @@ public class KeyListActivity extends DrawerActivity { return true; case R.id.menu_key_list_export_public: - mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB, null); + mExportHelper.showExportKeysDialog(null, + Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB, null); return true; case R.id.menu_key_list_secret_export: - mExportHelper.showExportKeysDialog(null, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC, null); + mExportHelper.showExportKeysDialog(null, Id.type.secret_key, + Constants.Path.APP_DIR_FILE_SEC, null); return true; default: diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 6da8a0262..3beb95108 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -190,12 +190,15 @@ public class KeyListFragment extends Fragment ProviderHelper.getPublicKeyRingsRowIds(getActivity()); for (int i = 0; i < ids.length; i++) { if (allPubRowIds.contains(ids[i])) { - masterKeyIds[i] = ProviderHelper.getPublicMasterKeyId(getActivity(), ids[i]); + masterKeyIds[i] = + ProviderHelper.getPublicMasterKeyId(getActivity(), ids[i]); } else { - masterKeyIds[i] = ProviderHelper.getSecretMasterKeyId(getActivity(), ids[i]); + masterKeyIds[i] = + ProviderHelper.getSecretMasterKeyId(getActivity(), ids[i]); } } - ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity()); + ExportHelper mExportHelper = + new ExportHelper((ActionBarActivity) getActivity()); mExportHelper .showExportKeysDialog(masterKeyIds, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB, diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index b86c20880..b8b2e271f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -124,7 +124,8 @@ public class ViewKeyActivity extends ActionBarActivity { return true; case R.id.menu_key_view_export_file: long masterKeyId = - ProviderHelper.getPublicMasterKeyId(this, Long.valueOf(mDataUri.getLastPathSegment())); + ProviderHelper.getPublicMasterKeyId(this, + Long.valueOf(mDataUri.getLastPathSegment())); long[] ids = new long[] {masterKeyId}; mExportHelper.showExportKeysDialog(ids, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB, null); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java index 4fccadf30..5631d40ea 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java @@ -267,6 +267,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable { * Based on OpenPGP Message Format */ public static String getAlgorithmFromId(int algorithmId) { - return (ALGORITHM_IDS.get(algorithmId) != null ? ALGORITHM_IDS.get(algorithmId) : ALGORITHM_IDS.get(-1)); + return (ALGORITHM_IDS.get(algorithmId) != null ? + ALGORITHM_IDS.get(algorithmId) : + ALGORITHM_IDS.get(-1)); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index 02ebde1c8..a467c779c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -166,9 +166,10 @@ public class DeleteKeyDialogFragment extends DialogFragment { masterKeyId = cursor.getLong(0); keyType = cursor.getLong(1); - Log.d(Constants.TAG, "masterKeyId: " + masterKeyId - + ", keyType:" + (keyType == KeychainContract.KeyTypes.PUBLIC ? "Public" : "Private")); - + Log.d(Constants.TAG, "masterKeyId: " + masterKeyId + + ", keyType:" + + (keyType == KeychainContract.KeyTypes.PUBLIC ? + "Public" : "Private")); if (keyType == KeychainContract.KeyTypes.SECRET) { if (mCheckDeleteSecret.isChecked() || mIsSingleSelection) { @@ -176,7 +177,8 @@ public class DeleteKeyDialogFragment extends DialogFragment { String.valueOf(masterKeyId), true); } } else { - ProviderHelper.deleteUnifiedKeyRing(activity, String.valueOf(masterKeyId), false); + ProviderHelper.deleteUnifiedKeyRing(activity, + String.valueOf(masterKeyId), false); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java index 94586810e..18403837a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java @@ -111,7 +111,7 @@ public class ShareQrCodeDialogFragment extends DialogFragment { content = keyringArmored.get(0); // OnClickListener are set in onResume to prevent automatic dismissing of Dialogs - // http://stackoverflow.com/questions/2620444/how-to-prevent-a-dialog-from-closing-when-a-button-is-clicked + // http://bit.ly/O5vfaR alert.setPositiveButton(R.string.btn_next, null); alert.setNegativeButton(android.R.string.cancel, null); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 1f5b13c83..de26e20a3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -94,11 +94,13 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("UTC")); date.set(year, monthOfYear, dayOfMonth); if (mOriginalExpiryDate != null) { - long numDays = (date.getTimeInMillis() / 86400000) - (mOriginalExpiryDate.getTimeInMillis() / 86400000); - if (numDays == 0) + long numDays = (date.getTimeInMillis() / 86400000) - + (mOriginalExpiryDate.getTimeInMillis() / 86400000); + if (numDays == 0) { setExpiryDate(mOriginalExpiryDate); - else + } else { setExpiryDate(date); + } } else { setExpiryDate(date); } @@ -316,11 +318,16 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { } public int getUsage() { - mUsage = (mUsage & ~KeyFlags.CERTIFY_OTHER) | (mChkCertify.isChecked() ? KeyFlags.CERTIFY_OTHER : 0); - mUsage = (mUsage & ~KeyFlags.SIGN_DATA) | (mChkSign.isChecked() ? KeyFlags.SIGN_DATA : 0); - mUsage = (mUsage & ~KeyFlags.ENCRYPT_COMMS) | (mChkEncrypt.isChecked() ? KeyFlags.ENCRYPT_COMMS : 0); - mUsage = (mUsage & ~KeyFlags.ENCRYPT_STORAGE) | (mChkEncrypt.isChecked() ? KeyFlags.ENCRYPT_STORAGE : 0); - mUsage = (mUsage & ~KeyFlags.AUTHENTICATION) | (mChkAuthenticate.isChecked() ? KeyFlags.AUTHENTICATION : 0); + mUsage = (mUsage & ~KeyFlags.CERTIFY_OTHER) | + (mChkCertify.isChecked() ? KeyFlags.CERTIFY_OTHER : 0); + mUsage = (mUsage & ~KeyFlags.SIGN_DATA) | + (mChkSign.isChecked() ? KeyFlags.SIGN_DATA : 0); + mUsage = (mUsage & ~KeyFlags.ENCRYPT_COMMS) | + (mChkEncrypt.isChecked() ? KeyFlags.ENCRYPT_COMMS : 0); + mUsage = (mUsage & ~KeyFlags.ENCRYPT_STORAGE) | + (mChkEncrypt.isChecked() ? KeyFlags.ENCRYPT_STORAGE : 0); + mUsage = (mUsage & ~KeyFlags.AUTHENTICATION) | + (mChkAuthenticate.isChecked() ? KeyFlags.AUTHENTICATION : 0); return mUsage; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index e4171cfae..fbf93aeda 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -69,20 +69,22 @@ public class HkpKeyServer extends KeyServer { /** * pub:%keyid%:%algo%:%keylen%:%creationdate%:%expirationdate%:%flags% *

    - *
  • %keyid% = this is either the fingerprint or the key ID of the key. Either the 16-digit or 8-digit - * key IDs are acceptable, but obviously the fingerprint is best.
  • + *
  • %keyid% = this is either the fingerprint or the key ID of the key. + * Either the 16-digit or 8-digit key IDs are acceptable, but obviously the fingerprint is best. + *
  • *
  • %algo% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc). * See RFC-2440
  • *
  • %keylen% = the key length (i.e. 1024, 2048, 4096, etc.)
  • *
  • %creationdate% = creation date of the key in standard - * RFC-2440 form (i.e. number of seconds since - * 1/1/1970 UTC time)
  • + * RFC-2440 form (i.e. number of + * seconds since 1/1/1970 UTC time) *
  • %expirationdate% = expiration date of the key in standard - * RFC-2440 form (i.e. number of seconds since - * 1/1/1970 UTC time)
  • - *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any order. The - * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so - * the absence of a given flag does not necessarily mean the absence of the detail. + * RFC-2440 form (i.e. number of + * seconds since 1/1/1970 UTC time)
  • + *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any + * order. The meaning of "disabled" is implementation-specific. Note that individual flags may + * be unimplemented, so the absence of a given flag does not necessarily mean the absence of the + * detail. *
      *
    • r == revoked
    • *
    • d == disabled
    • @@ -91,7 +93,8 @@ public class HkpKeyServer extends KeyServer { * *
    * - * @see 5.2. Machine Readable Indexes + * @see + * 5.2. Machine Readable Indexes * in Internet-Draft OpenPGP HTTP Keyserver Protocol Document */ public static final Pattern PUB_KEY_LINE = Pattern @@ -102,17 +105,19 @@ public class HkpKeyServer extends KeyServer { /** * uid:%escaped uid string%:%creationdate%:%expirationdate%:%flags% *
      - *
    • %escaped uid string% = the user ID string, with HTTP %-escaping for anything that isn't 7-bit - * safe as well as for the ":" character. Any other characters may be escaped, as desired.
    • + *
    • %escaped uid string% = the user ID string, with HTTP %-escaping for anything that + * isn't 7-bit safe as well as for the ":" character. Any other characters may be escaped, as + * desired.
    • *
    • %creationdate% = creation date of the key in standard - * RFC-2440 form (i.e. number of seconds since - * 1/1/1970 UTC time)
    • + * RFC-2440 form (i.e. number of + * seconds since 1/1/1970 UTC time) *
    • %expirationdate% = expiration date of the key in standard - * RFC-2440 form (i.e. number of seconds since - * 1/1/1970 UTC time)
    • - *
    • %flags% = letter codes to indicate details of the key, if any. Flags may be in any order. The - * meaning of "disabled" is implementation-specific. Note that individual flags may be unimplemented, so - * the absence of a given flag does not necessarily mean the absence of the detail. + * RFC-2440 form (i.e. number of + * seconds since 1/1/1970 UTC time)
    • + *
    • %flags% = letter codes to indicate details of the key, if any. Flags may be in any + * order. The meaning of "disabled" is implementation-specific. Note that individual flags may + * be unimplemented, so the absence of a given flag does not necessarily mean the absence of + * the detail. *
        *
      • r == revoked
      • *
      • d == disabled
      • @@ -244,8 +249,7 @@ public class HkpKeyServer extends KeyServer { entry.setAlgorithm(ImportKeysListEntry.getAlgorithmFromId(algorithmId)); // group 1 contains the full fingerprint (v4) or the long key id if available - // see https://bitbucket.org/skskeyserver/sks-keyserver/pull-request/12/fixes-for-machine-readable-indexes/diff - // and https://github.com/openpgp-keychain/openpgp-keychain/issues/259#issuecomment-38168176 + // see http://bit.ly/1d4bxbk and http://bit.ly/1gD1wwr String fingerprintOrKeyId = matcher.group(1); if (fingerprintOrKeyId.length() > 16) { entry.setFingerPrintHex(fingerprintOrKeyId.toLowerCase(Locale.US)); -- cgit v1.2.3 From 592ab31d866c9b58ce6e831b184301f665558e11 Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Wed, 2 Apr 2014 01:58:31 +0200 Subject: Add missing and curly brackets and fix others Style guide demands them even for single-line blocks, and opening curly brackets never appear on a line on their own. --- .../keychain/pgp/PgpKeyHelper.java | 15 ++++-- .../keychain/service/SaveKeyringParcel.java | 9 ++-- .../keychain/ui/EditKeyActivity.java | 8 ++-- .../ui/dialog/DeleteKeyDialogFragment.java | 3 +- .../keychain/ui/widget/KeyEditor.java | 19 ++++---- .../keychain/ui/widget/SectionView.java | 55 ++++++++++------------ .../keychain/ui/widget/UserIdEditor.java | 12 ++--- 7 files changed, 61 insertions(+), 60 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index 89352ef31..f4a5b8d4e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -300,8 +300,7 @@ public class PgpKeyHelper { return userId; } - public static int getKeyUsage(PGPSecretKey key) - { + public static int getKeyUsage(PGPSecretKey key) { return getKeyUsage(key.getPublicKey()); } @@ -310,13 +309,19 @@ public class PgpKeyHelper { int usage = 0; if (key.getVersion() >= 4) { for (PGPSignature sig : new IterableIterator(key.getSignatures())) { - if (key.isMasterKey() && sig.getKeyID() != key.getKeyID()) continue; + if (key.isMasterKey() && sig.getKeyID() != key.getKeyID()) { + continue; + } PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets(); - if (hashed != null) usage |= hashed.getKeyFlags(); + if (hashed != null) { + usage |= hashed.getKeyFlags(); + } PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets(); - if (unhashed != null) usage |= unhashed.getKeyFlags(); + if (unhashed != null) { + usage |= unhashed.getKeyFlags(); + } } } return usage; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index cc0f94b9b..7012bfafd 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -69,8 +69,7 @@ public class SaveKeyringParcel implements Parcelable { } @Override - public void writeToParcel(Parcel destination, int flags) - { + public void writeToParcel(Parcel destination, int flags) { destination.writeSerializable(userIDs); //might not be the best method to store. destination.writeSerializable(originalIDs); destination.writeSerializable(deletedIDs); @@ -78,8 +77,9 @@ public class SaveKeyringParcel implements Parcelable { destination.writeByte((byte) (primaryIDChanged ? 1 : 0)); destination.writeBooleanArray(moddedKeys); byte[] tmp = null; - if (deletedKeys.size() != 0) + if (deletedKeys.size() != 0) { tmp = PgpConversionHelper.PGPSecretKeyArrayListToBytes(deletedKeys); + } destination.writeByteArray(tmp); destination.writeSerializable(keysExpiryDates); destination.writeList(keysUsages); @@ -101,8 +101,7 @@ public class SaveKeyringParcel implements Parcelable { }; @Override - public int describeContents() - { + public int describeContents() { return 0; } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index a8b3e29ed..d0a0d20ad 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -391,8 +391,9 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener if (!isSet) { isSet = true; String[] parts = PgpKeyHelper.splitUserId(userId); - if (parts[0] != null) + if (parts[0] != null) { setTitle(parts[0]); + } } mUserIds.add(userId); } @@ -547,10 +548,11 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } String passphrase; - if (mIsPassPhraseSet) + if (mIsPassPhraseSet) { passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId); - else + } else { passphrase = ""; + } if (passphrase == null) { showPassphraseDialog(masterKeyId); } else { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index a467c779c..4de332d3c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -148,8 +148,9 @@ public class DeleteKeyDialogFragment extends DialogFragment { String selectionIDs = ""; for (int i = 0; i < keyRingRowIds.length; i++) { selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'"; - if (i + 1 < keyRingRowIds.length) + if (i + 1 < keyRingRowIds.length) { selectionIDs += ","; + } } selection += selectionIDs + ")"; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index de26e20a3..5fd06f4fc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -255,8 +255,9 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { } else { mUsage = PgpKeyHelper.getKeyUsage(key); mOriginalUsage = mUsage; - if (key.isMasterKey()) + if (key.isMasterKey()) { mChkCertify.setChecked(PgpKeyHelper.isCertificationKey(key)); + } mChkSign.setChecked(PgpKeyHelper.isSigningKey(key)); mChkEncrypt.setChecked(PgpKeyHelper.isEncryptionKey(key)); mChkAuthenticate.setChecked(PgpKeyHelper.isAuthenticationKey(key)); @@ -332,10 +333,10 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { return mUsage; } - public boolean needsSaving() - { - if (mIsNewKey) + public boolean needsSaving() { + if (mIsNewKey) { return true; + } boolean retval = (getUsage() != mOriginalUsage); @@ -345,21 +346,21 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { if (mOEDNull != mEDNull) { dateChanged = true; } else { - if(mOEDNull) //both null, no change + if (mOEDNull) { + //both null, no change dateChanged = false; - else + } else { dateChanged = ((mExpiryDate.compareTo(mOriginalExpiryDate)) != 0); + } } retval |= dateChanged; return retval; } - public boolean getIsNewKey() - { + public boolean getIsNewKey() { return mIsNewKey; } - } class ExpiryDatePickerDialog extends DatePickerDialog { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 150f6e221..1f388e865 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -164,34 +164,34 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor mEditors.setVisibility(hasChildren ? View.VISIBLE : View.GONE); } - public boolean needsSaving() - { + public boolean needsSaving() { //check each view for needs saving, take account of deleted items boolean ret = mOldItemDeleted; for (int i = 0; i < mEditors.getChildCount(); ++i) { Editor editor = (Editor) mEditors.getChildAt(i); ret |= editor.needsSaving(); - if (mType == Id.type.user_id) - ret |= ((UserIdEditor)editor).primarySwapped(); + if (mType == Id.type.user_id) { + ret |= ((UserIdEditor) editor).primarySwapped(); + } } return ret; } - public boolean primaryChanged() - { + public boolean primaryChanged() { boolean ret = false; for (int i = 0; i < mEditors.getChildCount(); ++i) { Editor editor = (Editor) mEditors.getChildAt(i); - if (mType == Id.type.user_id) - ret |= ((UserIdEditor)editor).primarySwapped(); + if (mType == Id.type.user_id) { + ret |= ((UserIdEditor) editor).primarySwapped(); + } } return ret; } - public String getOriginalPrimaryID() - { //NB: this will have to change when we change how Primary IDs are chosen, and so we need to be - // careful about where Master key capabilities are stored... multiple primaries and - // revoked ones make this harder than the simple case we are continuing to assume here + public String getOriginalPrimaryID() { + //NB: this will have to change when we change how Primary IDs are chosen, and so we need to be + // careful about where Master key capabilities are stored... multiple primaries and + // revoked ones make this harder than the simple case we are continuing to assume here for (int i = 0; i < mEditors.getChildCount(); ++i) { Editor editor = (Editor) mEditors.getChildAt(i); if (mType == Id.type.user_id) { @@ -203,16 +203,16 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor return null; } - public ArrayList getOriginalIDs() - { + public ArrayList getOriginalIDs() { ArrayList orig = new ArrayList(); if (mType == Id.type.user_id) { for (int i = 0; i < mEditors.getChildCount(); ++i) { UserIdEditor editor = (UserIdEditor) mEditors.getChildAt(i); - if (editor.isMainUserId()) + if (editor.isMainUserId()) { orig.add(0, editor.getOriginalID()); - else + } else { orig.add(editor.getOriginalID()); + } } return orig; } else { @@ -220,18 +220,15 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor } } - public ArrayList getDeletedIDs() - { + public ArrayList getDeletedIDs() { return mDeletedIDs; } - public ArrayList getDeletedKeys() - { + public ArrayList getDeletedKeys() { return mDeletedKeys; } - public List getNeedsSavingArray() - { + public List getNeedsSavingArray() { ArrayList mList = new ArrayList(); for (int i = 0; i < mEditors.getChildCount(); ++i) { Editor editor = (Editor) mEditors.getChildAt(i); @@ -240,21 +237,20 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor return mList; } - public List getNewIDFlags() - { + public List getNewIDFlags() { ArrayList mList = new ArrayList(); for (int i = 0; i < mEditors.getChildCount(); ++i) { UserIdEditor editor = (UserIdEditor) mEditors.getChildAt(i); - if (editor.isMainUserId()) + if (editor.isMainUserId()) { mList.add(0, editor.getIsNewID()); - else + } else { mList.add(editor.getIsNewID()); + } } return mList; } - public List getNewKeysArray() - { + public List getNewKeysArray() { ArrayList mList = new ArrayList(); if (mType == Id.type.key) { for (int i = 0; i < mEditors.getChildCount(); ++i) { @@ -420,8 +416,9 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor mEditors, false); view.setEditorListener(SectionView.this); int usage = 0; - if (mEditors.getChildCount() == 0) + if (mEditors.getChildCount() == 0) { usage = PGPKeyFlags.CAN_CERTIFY; + } view.setValue(newKey, newKey.isMasterKey(), usage, true); mEditors.addView(view); SectionView.this.updateEditorsVisible(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index 71f5f0d86..b21b99254 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -84,8 +84,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene } @Override - public void afterTextChanged(Editable s) - { + public void afterTextChanged(Editable s) { if (mEditorListener != null) { mEditorListener.onEdited(); } @@ -246,18 +245,15 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene return retval; } - public boolean getIsOriginallyMainUserID() - { + public boolean getIsOriginallyMainUserID() { return mOriginallyMainUserID; } - public boolean primarySwapped() - { + public boolean primarySwapped() { return (mOriginallyMainUserID != isMainUserId()); } - public String getOriginalID() - { + public String getOriginalID() { return mOriginalID; } -- cgit v1.2.3 From a3a5085afb4ffa07093139176795d878a474f8d6 Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Wed, 2 Apr 2014 13:21:11 +0200 Subject: Spacing corrections --- .../java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index d0a0d20ad..e0286b566 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -568,15 +568,14 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } } - private void checkEmptyIDsWanted() - { + private void checkEmptyIDsWanted() { try { ArrayList userIDs = getUserIds(mUserIdsView); List newIDs = mUserIdsView.getNewIDFlags(); ArrayList originalIDs = mUserIdsView.getOriginalIDs(); int curID = 0; for (String userID : userIDs) { - if ( userID.equals("") && (!userID.equals(originalIDs.get(curID)) || newIDs.get(curID) ) ) { + if (userID.equals("") && (!userID.equals(originalIDs.get(curID)) || newIDs.get(curID))) { AlertDialog.Builder alert = new AlertDialog.Builder( EditKeyActivity.this); -- cgit v1.2.3 From 77a6c509f70d7c7fb78e22573dd5785ec3895eeb Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Wed, 2 Apr 2014 13:34:42 +0200 Subject: Replace wildcard imports with explicit imports --- .../keychain/provider/ProviderHelper.java | 6 +++- .../keychain/service/KeychainIntentService.java | 36 +++++++++++++++++++--- .../keychain/service/PassphraseCacheService.java | 9 +++++- .../keychain/ui/CertifyKeyActivity.java | 8 ++++- .../keychain/ui/DrawerActivity.java | 13 ++++++-- .../keychain/ui/ImportKeysListFragment.java | 6 +++- .../keychain/ui/KeyListFragment.java | 20 ++++++++++-- .../keychain/ui/PreferencesActivity.java | 8 ++++- .../keychain/ui/SelectPublicKeyFragment.java | 8 ++++- .../ui/adapter/KeyValueSpinnerAdapter.java | 6 +++- .../keychain/ui/widget/UserIdEditor.java | 6 +++- .../keychain/util/HkpKeyServer.java | 15 +++++++-- .../keychain/util/PausableThreadPoolExecutor.java | 6 +++- 13 files changed, 126 insertions(+), 21 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 6882b6925..133b4e7f7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -17,7 +17,11 @@ package org.sufficientlysecure.keychain.provider; -import android.content.*; +import android.content.ContentProviderOperation; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.OperationApplicationException; import android.database.Cursor; import android.database.DatabaseUtils; import android.net.Uri; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 487da80ca..2a1b0be2e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -26,21 +26,47 @@ import android.os.Messenger; import android.os.RemoteException; import org.spongycastle.bcpg.sig.KeyFlags; -import org.spongycastle.openpgp.*; +import org.spongycastle.openpgp.PGPKeyRing; +import org.spongycastle.openpgp.PGPObjectFactory; +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.spongycastle.openpgp.PGPUtil; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.helper.Preferences; -import org.sufficientlysecure.keychain.pgp.*; +import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; +import org.sufficientlysecure.keychain.pgp.PgpHelper; +import org.sufficientlysecure.keychain.pgp.PgpImportExport; +import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; -import org.sufficientlysecure.keychain.util.*; - -import java.io.*; +import org.sufficientlysecure.keychain.util.HkpKeyServer; +import org.sufficientlysecure.keychain.util.InputData; +import org.sufficientlysecure.keychain.util.KeychainServiceListener; +import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; +import org.sufficientlysecure.keychain.util.ProgressScaler; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.List; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index 7ab40491f..bdce9069e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -24,7 +24,14 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.os.*; +import android.os.Binder; +import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException; import android.support.v4.util.LongSparseArray; import android.util.Log; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index e7da531e1..8f7c82e8f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -32,8 +32,14 @@ import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity; import android.view.View; import android.view.View.OnClickListener; -import android.widget.*; +import android.widget.ArrayAdapter; +import android.widget.CheckBox; +import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.ListView; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.Toast; import com.beardedhen.androidbootstrap.BootstrapButton; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.sufficientlysecure.keychain.Constants; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java index e5a8fa8bc..17dce0221 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java @@ -27,9 +27,18 @@ import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarActivity; -import android.view.*; -import android.widget.*; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; + import com.beardedhen.androidbootstrap.FontAwesomeText; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index 9e8506193..077fa0cab 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -29,7 +29,11 @@ import com.devspark.appmsg.AppMsg; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.Preferences; -import org.sufficientlysecure.keychain.ui.adapter.*; +import org.sufficientlysecure.keychain.ui.adapter.AsyncTaskResultWrapper; +import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter; +import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; +import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListLoader; +import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListServerLoader; import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.KeyServer; import org.sufficientlysecure.keychain.util.Log; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 3beb95108..1428a51f5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -24,7 +24,11 @@ import android.content.Intent; import android.database.Cursor; import android.graphics.Color; import android.net.Uri; -import android.os.*; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; @@ -33,11 +37,21 @@ import android.support.v4.view.MenuItemCompat; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.text.TextUtils; -import android.view.*; +import android.view.ActionMode; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; import android.view.View.OnClickListener; +import android.view.ViewGroup; import android.view.animation.AnimationUtils; -import android.widget.*; import android.widget.AbsListView.MultiChoiceModeListener; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.ListView; +import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java index c541e8a23..54d37c72f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java @@ -20,9 +20,15 @@ import android.annotation.SuppressLint; import android.content.Intent; import android.os.Build; import android.os.Bundle; -import android.preference.*; +import android.preference.CheckBoxPreference; +import android.preference.Preference; +import android.preference.PreferenceActivity; +import android.preference.PreferenceFragment; +import android.preference.PreferenceScreen; + import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.openpgp.PGPEncryptedData; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java index 6ab9f1c6e..2be5c12c3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java @@ -32,7 +32,13 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.*; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.TextView; + import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ListFragmentWorkaround; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java index c997599bd..5b5d316b6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java @@ -20,7 +20,11 @@ package org.sufficientlysecure.keychain.ui.adapter; import android.content.Context; import android.widget.ArrayAdapter; -import java.util.*; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; public class KeyValueSpinnerAdapter extends ArrayAdapter { private final HashMap mData; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index b21b99254..4b2387afb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -24,7 +24,11 @@ import android.util.Patterns; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; -import android.widget.*; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.RadioButton; import com.beardedhen.androidbootstrap.BootstrapButton; import org.sufficientlysecure.keychain.R; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index fbf93aeda..5efc732e4 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -29,6 +29,7 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; @@ -37,8 +38,18 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; -import java.net.*; -import java.util.*; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PausableThreadPoolExecutor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PausableThreadPoolExecutor.java index 377a8d5d6..5ec915810 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PausableThreadPoolExecutor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PausableThreadPoolExecutor.java @@ -17,7 +17,11 @@ package org.sufficientlysecure.keychain.util; -import java.util.concurrent.*; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; -- cgit v1.2.3 From fc29fadd51da5bed9c8c1841f65bb20aacd9c5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 2 Apr 2014 13:54:38 +0200 Subject: Fix build --- .../org/sufficientlysecure/keychain/service/KeychainIntentService.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 2a1b0be2e..1c334e6d6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -41,11 +41,13 @@ import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpImportExport; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; +import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; import org.sufficientlysecure.keychain.provider.ProviderHelper; -- cgit v1.2.3 From 6ac13d9f6933bf72950910b0e2831761dd8c434b Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Wed, 2 Apr 2014 15:31:03 +0200 Subject: Rename "pass phrase" to "passphrase" --- .../org/sufficientlysecure/keychain/Constants.java | 2 +- .../keychain/helper/Preferences.java | 8 ++--- .../keychain/pgp/PgpKeyOperation.java | 42 +++++++++++----------- .../keychain/service/KeychainIntentService.java | 18 +++++----- .../keychain/service/PassphraseCacheService.java | 2 +- .../keychain/service/SaveKeyringParcel.java | 12 +++---- .../keychain/ui/EditKeyActivity.java | 40 ++++++++++----------- .../keychain/ui/EncryptFileFragment.java | 4 +-- .../keychain/ui/EncryptMessageFragment.java | 4 +-- .../keychain/ui/PreferencesActivity.java | 14 ++++---- 10 files changed, 73 insertions(+), 73 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 5062800db..84c7f0f41 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -58,7 +58,7 @@ public final class Constants { public static final String DEFAULT_ASCII_ARMOUR = "defaultAsciiArmour"; public static final String DEFAULT_MESSAGE_COMPRESSION = "defaultMessageCompression"; public static final String DEFAULT_FILE_COMPRESSION = "defaultFileCompression"; - public static final String PASS_PHRASE_CACHE_TTL = "passphraseCacheTtl"; + public static final String PASSPHRASE_CACHE_TTL = "passphraseCacheTtl"; public static final String LANGUAGE = "language"; public static final String FORCE_V3_SIGNATURES = "forceV3Signatures"; public static final String KEY_SERVERS = "keyServers"; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java index 13b1df4d4..e91572ade 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java @@ -58,8 +58,8 @@ public class Preferences { editor.commit(); } - public long getPassPhraseCacheTtl() { - int ttl = mSharedPreferences.getInt(Constants.Pref.PASS_PHRASE_CACHE_TTL, 180); + public long getPassphraseCacheTtl() { + int ttl = mSharedPreferences.getInt(Constants.Pref.PASSPHRASE_CACHE_TTL, 180); // fix the value if it was set to "never" in previous versions, which currently is not // supported if (ttl == 0) { @@ -68,9 +68,9 @@ public class Preferences { return (long) ttl; } - public void setPassPhraseCacheTtl(int value) { + public void setPassphraseCacheTtl(int value) { SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putInt(Constants.Pref.PASS_PHRASE_CACHE_TTL, value); + editor.putInt(Constants.Pref.PASSPHRASE_CACHE_TTL, value); editor.commit(); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index ceccf7a70..48b959738 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -195,25 +195,25 @@ public class PgpKeyOperation { sha1Calc, isMasterKey, keyEncryptor); } - public PGPSecretKeyRing changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassPhrase, - String newPassPhrase) + public PGPSecretKeyRing changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassphrase, + String newPassphrase) throws IOException, PGPException, NoSuchProviderException { updateProgress(R.string.progress_building_key, 0, 100); - if (oldPassPhrase == null) { - oldPassPhrase = ""; + if (oldPassphrase == null) { + oldPassphrase = ""; } - if (newPassPhrase == null) { - newPassPhrase = ""; + if (newPassphrase == null) { + newPassphrase = ""; } PGPSecretKeyRing newKeyRing = PGPSecretKeyRing.copyWithNewPassword( keyRing, new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build()).setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassPhrase.toCharArray()), + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassphrase.toCharArray()), new JcePBESecretKeyEncryptorBuilder(keyRing.getSecretKey() - .getKeyEncryptionAlgorithm()).build(newPassPhrase.toCharArray())); + .getKeyEncryptionAlgorithm()).build(newPassphrase.toCharArray())); return newKeyRing; @@ -223,7 +223,7 @@ public class PgpKeyOperation { ArrayList userIds, ArrayList keys, ArrayList keysExpiryDates, ArrayList keysUsages, - String newPassPhrase, String oldPassPhrase) + String newPassphrase, String oldPassphrase) throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException { int usageId = keysUsages.get(0); @@ -236,7 +236,7 @@ public class PgpKeyOperation { PGPPublicKey masterPublicKey = masterKey.getPublicKey(); PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassPhrase.toCharArray()); + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassphrase.toCharArray()); PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor); updateProgress(R.string.progress_certifying_master_key, 20, 100); @@ -294,7 +294,7 @@ public class PgpKeyOperation { PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder( PGPEncryptedData.CAST5, sha1Calc) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - newPassPhrase.toCharArray()); + newPassphrase.toCharArray()); PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(), @@ -310,7 +310,7 @@ public class PgpKeyOperation { PBESecretKeyDecryptor keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - oldPassPhrase.toCharArray()); + oldPassphrase.toCharArray()); PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2); // TODO: now used without algorithm and creation time?! (APG 1) @@ -375,16 +375,16 @@ public class PgpKeyOperation { updateProgress(R.string.progress_building_key, 0, 100); PGPSecretKey masterKey = saveParcel.keys.get(0); - if (saveParcel.oldPassPhrase == null) { - saveParcel.oldPassPhrase = ""; + if (saveParcel.oldPassphrase == null) { + saveParcel.oldPassphrase = ""; } - if (saveParcel.newPassPhrase == null) { - saveParcel.newPassPhrase = ""; + if (saveParcel.newPassphrase == null) { + saveParcel.newPassphrase = ""; } if (mKR == null) { return buildNewSecretKey(saveParcel.userIDs, saveParcel.keys, saveParcel.keysExpiryDates, - saveParcel.keysUsages, saveParcel.newPassPhrase, saveParcel.oldPassPhrase); //new Keyring + saveParcel.keysUsages, saveParcel.newPassphrase, saveParcel.oldPassphrase); //new Keyring } /* @@ -423,7 +423,7 @@ public class PgpKeyOperation { String mainUserId = saveParcel.userIDs.get(0); PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(saveParcel.oldPassPhrase.toCharArray()); + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(saveParcel.oldPassphrase.toCharArray()); PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor); updateProgress(R.string.progress_certifying_master_key, 20, 100); @@ -565,7 +565,7 @@ public class PgpKeyOperation { PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder( PGPEncryptedData.CAST5, sha1Calc) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - saveParcel.oldPassPhrase.toCharArray()); + saveParcel.oldPassphrase.toCharArray()); //this generates one more signature than necessary... PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, @@ -586,7 +586,7 @@ public class PgpKeyOperation { } else { keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - saveParcel.oldPassPhrase.toCharArray()); + saveParcel.oldPassphrase.toCharArray()); } PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2); PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey, subPrivateKey); @@ -667,7 +667,7 @@ public class PgpKeyOperation { PBESecretKeyEncryptor keyEncryptorNew = new JcePBESecretKeyEncryptorBuilder( PGPEncryptedData.CAST5, sha1Calc) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - saveParcel.newPassPhrase.toCharArray()); + saveParcel.newPassphrase.toCharArray()); //update the passphrase mKR = PGPSecretKeyRing.copyWithNewPassword(mKR, keyDecryptor, keyEncryptorNew); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 1c334e6d6..e9c949246 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -488,16 +488,16 @@ public class KeychainIntentService extends IntentService try { /* Input */ SaveKeyringParcel saveParams = data.getParcelable(SAVE_KEYRING_PARCEL); - String oldPassPhrase = saveParams.oldPassPhrase; - String newPassPhrase = saveParams.newPassPhrase; + String oldPassphrase = saveParams.oldPassphrase; + String newPassphrase = saveParams.newPassphrase; boolean canSign = true; if (data.containsKey(SAVE_KEYRING_CAN_SIGN)) { canSign = data.getBoolean(SAVE_KEYRING_CAN_SIGN); } - if (newPassPhrase == null) { - newPassPhrase = oldPassPhrase; + if (newPassphrase == null) { + newPassphrase = oldPassphrase; } long masterKeyId = saveParams.keys.get(0).getKeyID(); @@ -508,7 +508,7 @@ public class KeychainIntentService extends IntentService PGPSecretKeyRing keyRing = ProviderHelper .getPGPSecretKeyRingByKeyId(this, masterKeyId); keyRing = keyOperations.changeSecretKeyPassphrase(keyRing, - oldPassPhrase, newPassPhrase); + oldPassphrase, newPassphrase); setProgress(R.string.progress_saving_key_ring, 50, 100); ProviderHelper.saveKeyRing(this, keyRing); setProgress(R.string.progress_done, 100, 100); @@ -526,7 +526,7 @@ public class KeychainIntentService extends IntentService ProviderHelper.saveKeyRing(this, pair.second); setProgress(R.string.progress_done, 100, 100); } - PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassPhrase); + PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassphrase); /* Output */ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY); @@ -816,9 +816,9 @@ public class KeychainIntentService extends IntentService ArrayList userIds = data.getStringArrayList(CERTIFY_KEY_UIDS); /* Operation */ - String signaturePassPhrase = PassphraseCacheService.getCachedPassphrase(this, + String signaturePassphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId); - if (signaturePassPhrase == null) { + if (signaturePassphrase == null) { throw new PgpGeneralException("Unable to obtain passphrase"); } @@ -829,7 +829,7 @@ public class KeychainIntentService extends IntentService PGPSecretKey certificationKey = PgpKeyHelper.getCertificationKey(this, masterKeyId); publicKey = keyOperation.certifyKey(certificationKey, publicKey, - userIds, signaturePassPhrase); + userIds, signaturePassphrase); publicRing = PGPPublicKeyRing.insertPublicKey(publicRing, publicKey); // store the signed key in our local cache diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index bdce9069e..a4b6ab6b9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -95,7 +95,7 @@ public class PassphraseCacheService extends Service { Intent intent = new Intent(context, PassphraseCacheService.class); intent.setAction(ACTION_PASSPHRASE_CACHE_ADD); - intent.putExtra(EXTRA_TTL, Preferences.getPreferences(context).getPassPhraseCacheTtl()); + intent.putExtra(EXTRA_TTL, Preferences.getPreferences(context).getPassphraseCacheTtl()); intent.putExtra(EXTRA_PASSPHRASE, passphrase); intent.putExtra(EXTRA_KEY_ID, keyId); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index 7012bfafd..7c2dcf2c1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -38,8 +38,8 @@ public class SaveKeyringParcel implements Parcelable { public ArrayList deletedKeys; public ArrayList keysExpiryDates; public ArrayList keysUsages; - public String newPassPhrase; - public String oldPassPhrase; + public String newPassphrase; + public String oldPassphrase; public boolean[] newKeys; public ArrayList keys; public String originalPrimaryID; @@ -61,8 +61,8 @@ public class SaveKeyringParcel implements Parcelable { } keysExpiryDates = (ArrayList) source.readSerializable(); keysUsages = source.readArrayList(Integer.class.getClassLoader()); - newPassPhrase = source.readString(); - oldPassPhrase = source.readString(); + newPassphrase = source.readString(); + oldPassphrase = source.readString(); newKeys = source.createBooleanArray(); keys = PgpConversionHelper.BytesToPGPSecretKeyList(source.createByteArray()); originalPrimaryID = source.readString(); @@ -83,8 +83,8 @@ public class SaveKeyringParcel implements Parcelable { destination.writeByteArray(tmp); destination.writeSerializable(keysExpiryDates); destination.writeList(keysUsages); - destination.writeString(newPassPhrase); - destination.writeString(oldPassPhrase); + destination.writeString(newPassphrase); + destination.writeString(oldPassphrase); destination.writeBooleanArray(newKeys); destination.writeByteArray(PgpConversionHelper.PGPSecretKeyArrayListToBytes(keys)); destination.writeString(originalPrimaryID); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index e0286b566..30636f849 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -97,9 +97,9 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener private SectionView mKeysView; private String mCurrentPassphrase = null; - private String mNewPassPhrase = null; - private String mSavedNewPassPhrase = null; - private boolean mIsPassPhraseSet; + private String mNewPassphrase = null; + private String mSavedNewPassphrase = null; + private boolean mIsPassphraseSet; private boolean mNeedsSaving; private boolean mIsBrandNewKeyring = false; @@ -403,8 +403,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener mCurrentPassphrase = ""; buildLayout(false); - mIsPassPhraseSet = PassphraseCacheService.hasPassphrase(this, masterKeyId); - if (!mIsPassPhraseSet) { + mIsPassphraseSet = PassphraseCacheService.hasPassphrase(this, masterKeyId); + if (!mIsPassphraseSet) { // check "no passphrase" checkbox and remove button mNoPassphrase.setChecked(true); mChangePassphrase.setVisibility(View.GONE); @@ -423,10 +423,10 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener Bundle data = message.getData(); // set new returned passphrase! - mNewPassPhrase = data + mNewPassphrase = data .getString(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE); - updatePassPhraseButtonText(); + updatePassphraseButtonText(); somethingChanged(); } } @@ -466,7 +466,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout container = (LinearLayout) findViewById(R.id.edit_key_container); - if (mIsPassPhraseSet) { + if (mIsPassphraseSet) { mChangePassphrase.setText(getString(R.string.btn_change_passphrase)); } mUserIdsView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); @@ -482,7 +482,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener mKeysView.setEditorListener(this); container.addView(mKeysView); - updatePassPhraseButtonText(); + updatePassphraseButtonText(); mChangePassphrase.setOnClickListener(new OnClickListener() { public void onClick(View v) { @@ -497,11 +497,11 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { // remove passphrase - mSavedNewPassPhrase = mNewPassPhrase; - mNewPassPhrase = ""; + mSavedNewPassphrase = mNewPassphrase; + mNewPassphrase = ""; mChangePassphrase.setVisibility(View.GONE); } else { - mNewPassPhrase = mSavedNewPassPhrase; + mNewPassphrase = mSavedNewPassphrase; mChangePassphrase.setVisibility(View.VISIBLE); } somethingChanged(); @@ -519,8 +519,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public boolean isPassphraseSet() { if (mNoPassphrase.isChecked()) { return true; - } else if ((mIsPassPhraseSet) - || (mNewPassPhrase != null && !mNewPassPhrase.equals(""))) { + } else if ((mIsPassphraseSet) + || (mNewPassphrase != null && !mNewPassphrase.equals(""))) { return true; } else { return false; @@ -530,9 +530,9 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener public boolean hasPassphraseChanged() { if (mNoPassphrase != null) { if (mNoPassphrase.isChecked()) { - return mIsPassPhraseSet; + return mIsPassphraseSet; } else { - return (mNewPassPhrase != null && !mNewPassPhrase.equals("")); + return (mNewPassphrase != null && !mNewPassphrase.equals("")); } } else { return false; @@ -548,7 +548,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } String passphrase; - if (mIsPassPhraseSet) { + if (mIsPassphraseSet) { passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId); } else { passphrase = ""; @@ -638,8 +638,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener saveParams.deletedKeys = mKeysView.getDeletedKeys(); saveParams.keysExpiryDates = getKeysExpiryDates(mKeysView); saveParams.keysUsages = getKeysUsages(mKeysView); - saveParams.newPassPhrase = mNewPassPhrase; - saveParams.oldPassPhrase = mCurrentPassphrase; + saveParams.newPassphrase = mNewPassphrase; + saveParams.oldPassphrase = mCurrentPassphrase; saveParams.newKeys = toPrimitiveArray(mKeysView.getNewKeysArray()); saveParams.keys = getKeys(mKeysView); saveParams.originalPrimaryID = mUserIdsView.getOriginalPrimaryID(); @@ -819,7 +819,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener return keysExpiryDates; } - private void updatePassPhraseButtonText() { + private void updatePassphraseButtonText() { mChangePassphrase.setText(isPassphraseSet() ? getString(R.string.btn_change_passphrase) : getString(R.string.btn_set_passphrase)); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java index c8ea6ffb7..8b440a552 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java @@ -224,9 +224,9 @@ public class EncryptFileFragment extends Fragment { if (mEncryptInterface.isModeSymmetric()) { // symmetric encryption - boolean gotPassPhrase = (mEncryptInterface.getPassphrase() != null + boolean gotPassphrase = (mEncryptInterface.getPassphrase() != null && mEncryptInterface.getPassphrase().length() != 0); - if (!gotPassPhrase) { + if (!gotPassphrase) { AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT) .show(); return; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java index 4522acf4e..a7818a1d8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java @@ -125,9 +125,9 @@ public class EncryptMessageFragment extends Fragment { if (mEncryptInterface.isModeSymmetric()) { // symmetric encryption - boolean gotPassPhrase = (mEncryptInterface.getPassphrase() != null + boolean gotPassphrase = (mEncryptInterface.getPassphrase() != null && mEncryptInterface.getPassphrase().length() != 0); - if (!gotPassPhrase) { + if (!gotPassphrase) { AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT) .show(); return; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java index 54d37c72f..57841edde 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java @@ -61,8 +61,8 @@ public class PreferencesActivity extends PreferenceActivity { if (action != null && action.equals(ACTION_PREFS_GEN)) { addPreferencesFromResource(R.xml.gen_preferences); - initializePassPassPhraceCacheTtl( - (IntegerListPreference) findPreference(Constants.Pref.PASS_PHRASE_CACHE_TTL)); + initializePassPassphraceCacheTtl( + (IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL)); mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS); String servers[] = sPreferences.getKeyServers(); @@ -165,8 +165,8 @@ public class PreferencesActivity extends PreferenceActivity { // Load the preferences from an XML resource addPreferencesFromResource(R.xml.gen_preferences); - initializePassPassPhraceCacheTtl( - (IntegerListPreference) findPreference(Constants.Pref.PASS_PHRASE_CACHE_TTL)); + initializePassPassphraceCacheTtl( + (IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL)); mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS); String servers[] = sPreferences.getKeyServers(); @@ -261,15 +261,15 @@ public class PreferencesActivity extends PreferenceActivity { || super.isValidFragment(fragmentName); } - private static void initializePassPassPhraceCacheTtl(final IntegerListPreference mPassphraseCacheTtl) { - mPassphraseCacheTtl.setValue("" + sPreferences.getPassPhraseCacheTtl()); + private static void initializePassPassphraceCacheTtl(final IntegerListPreference mPassphraseCacheTtl) { + mPassphraseCacheTtl.setValue("" + sPreferences.getPassphraseCacheTtl()); mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry()); mPassphraseCacheTtl .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { mPassphraseCacheTtl.setValue(newValue.toString()); mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry()); - sPreferences.setPassPhraseCacheTtl(Integer.parseInt(newValue.toString())); + sPreferences.setPassphraseCacheTtl(Integer.parseInt(newValue.toString())); return false; } }); -- cgit v1.2.3 From c4c9713da467d2d1f1d7d1cb50d72524d769b21b Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Wed, 2 Apr 2014 15:36:32 +0200 Subject: Rename "armour" to "armor" --- .../org/sufficientlysecure/keychain/Constants.java | 2 +- .../keychain/helper/Preferences.java | 8 ++++---- .../keychain/ui/EncryptFileFragment.java | 4 ++-- .../keychain/ui/PreferencesActivity.java | 18 +++++++++--------- 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 84c7f0f41..5b9f53b09 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -55,7 +55,7 @@ public final class Constants { public static final class Pref { public static final String DEFAULT_ENCRYPTION_ALGORITHM = "defaultEncryptionAlgorithm"; public static final String DEFAULT_HASH_ALGORITHM = "defaultHashAlgorithm"; - public static final String DEFAULT_ASCII_ARMOUR = "defaultAsciiArmour"; + public static final String DEFAULT_ASCII_ARMOR = "defaultAsciiArmor"; public static final String DEFAULT_MESSAGE_COMPRESSION = "defaultMessageCompression"; public static final String DEFAULT_FILE_COMPRESSION = "defaultFileCompression"; public static final String PASSPHRASE_CACHE_TTL = "passphraseCacheTtl"; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java index e91572ade..ca5555fea 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java @@ -118,13 +118,13 @@ public class Preferences { editor.commit(); } - public boolean getDefaultAsciiArmour() { - return mSharedPreferences.getBoolean(Constants.Pref.DEFAULT_ASCII_ARMOUR, false); + public boolean getDefaultAsciiArmor() { + return mSharedPreferences.getBoolean(Constants.Pref.DEFAULT_ASCII_ARMOR, false); } - public void setDefaultAsciiArmour(boolean value) { + public void setDefaultAsciiArmor(boolean value) { SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putBoolean(Constants.Pref.DEFAULT_ASCII_ARMOUR, value); + editor.putBoolean(Constants.Pref.DEFAULT_ASCII_ARMOR, value); editor.commit(); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java index 8b440a552..01422ea13 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java @@ -138,8 +138,8 @@ public class EncryptFileFragment extends Fragment { mDeleteAfter = (CheckBox) view.findViewById(R.id.deleteAfterEncryption); mShareAfter = (CheckBox) view.findViewById(R.id.shareAfterEncryption); - mAsciiArmor = (CheckBox) view.findViewById(R.id.asciiArmour); - mAsciiArmor.setChecked(Preferences.getPreferences(getActivity()).getDefaultAsciiArmour()); + mAsciiArmor = (CheckBox) view.findViewById(R.id.asciiArmor); + mAsciiArmor.setChecked(Preferences.getPreferences(getActivity()).getDefaultAsciiArmor()); return view; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java index 57841edde..265bb2139 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java @@ -110,8 +110,8 @@ public class PreferencesActivity extends PreferenceActivity { (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_FILE_COMPRESSION), entries, values); - initializeAsciiArmour( - (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOUR)); + initializeAsciiArmor( + (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOR)); initializeForceV3Signatures( (CheckBoxPreference) findPreference(Constants.Pref.FORCE_V3_SIGNATURES)); @@ -247,8 +247,8 @@ public class PreferencesActivity extends PreferenceActivity { (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_FILE_COMPRESSION), entries, values); - initializeAsciiArmour( - (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOUR)); + initializeAsciiArmor( + (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOR)); initializeForceV3Signatures( (CheckBoxPreference) findPreference(Constants.Pref.FORCE_V3_SIGNATURES)); @@ -362,12 +362,12 @@ public class PreferencesActivity extends PreferenceActivity { }); } - private static void initializeAsciiArmour(final CheckBoxPreference mAsciiArmour) { - mAsciiArmour.setChecked(sPreferences.getDefaultAsciiArmour()); - mAsciiArmour.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + private static void initializeAsciiArmor(final CheckBoxPreference mAsciiArmor) { + mAsciiArmor.setChecked(sPreferences.getDefaultAsciiArmor()); + mAsciiArmor.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { - mAsciiArmour.setChecked((Boolean) newValue); - sPreferences.setDefaultAsciiArmour((Boolean) newValue); + mAsciiArmor.setChecked((Boolean) newValue); + sPreferences.setDefaultAsciiArmor((Boolean) newValue); return false; } }); -- cgit v1.2.3 From 7a66ccb5ee5d3de8f3814267969139397de45e12 Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Wed, 2 Apr 2014 15:43:29 +0200 Subject: Rename "canEdit" to "canBeEdited" --- .../sufficientlysecure/keychain/ui/EditKeyActivity.java | 4 ++-- .../sufficientlysecure/keychain/ui/widget/KeyEditor.java | 4 ++-- .../sufficientlysecure/keychain/ui/widget/SectionView.java | 14 +++++++------- .../keychain/ui/widget/UserIdEditor.java | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 30636f849..b0cca4a7a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -471,13 +471,13 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } mUserIdsView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); mUserIdsView.setType(Id.type.user_id); - mUserIdsView.setCanEdit(mMasterCanSign); + mUserIdsView.setCanBeEdited(mMasterCanSign); mUserIdsView.setUserIds(mUserIds); mUserIdsView.setEditorListener(this); container.addView(mUserIdsView); mKeysView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); mKeysView.setType(Id.type.key); - mKeysView.setCanEdit(mMasterCanSign); + mKeysView.setCanBeEdited(mMasterCanSign); mKeysView.setKeys(mKeys, mKeysUsages, newKeys); mKeysView.setEditorListener(this); container.addView(mKeysView); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 5fd06f4fc..c7bd1c987 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -196,8 +196,8 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { super.onFinishInflate(); } - public void setCanEdit(boolean bCanEdit) { - if (!bCanEdit) { + public void setCanBeEdited(boolean canBeEdited) { + if (!canBeEdited) { mDeleteButton.setVisibility(View.INVISIBLE); mExpiryDateButton.setEnabled(false); mChkSign.setEnabled(false); //certify is always disabled diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index 1f388e865..fb59cd3b7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -64,7 +64,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor private boolean mOldItemDeleted = false; private ArrayList mDeletedIDs = new ArrayList(); private ArrayList mDeletedKeys = new ArrayList(); - private boolean mCanEdit = true; + private boolean mCanBeEdited = true; private ActionBarActivity mActivity; @@ -107,9 +107,9 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor } } - public void setCanEdit(boolean bCanEdit) { - mCanEdit = bCanEdit; - if (!mCanEdit) { + public void setCanBeEdited(boolean canBeEdited) { + mCanBeEdited = canBeEdited; + if (!mCanBeEdited) { mPlusButton.setVisibility(View.INVISIBLE); } } @@ -265,7 +265,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor * {@inheritDoc} */ public void onClick(View v) { - if (mCanEdit) { + if (mCanBeEdited) { switch (mType) { case Id.type.user_id: { UserIdEditor view = (UserIdEditor) mInflater.inflate( @@ -315,7 +315,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor mEditors, false); view.setEditorListener(this); view.setValue(userId, mEditors.getChildCount() == 0, false); - view.setCanEdit(mCanEdit); + view.setCanBeEdited(mCanBeEdited); mEditors.addView(view); } @@ -336,7 +336,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor view.setEditorListener(this); boolean isMasterKey = (mEditors.getChildCount() == 0); view.setValue(list.get(i), isMasterKey, usages.get(i), newKeys); - view.setCanEdit(mCanEdit); + view.setCanBeEdited(mCanBeEdited); mEditors.addView(view); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index 4b2387afb..2253872d5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -52,8 +52,8 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene private boolean mOriginallyMainUserID; private boolean mIsNewId; - public void setCanEdit(boolean bCanEdit) { - if (!bCanEdit) { + public void setCanBeEdited(boolean canBeEdited) { + if (!canBeEdited) { mDeleteButton.setVisibility(View.INVISIBLE); mName.setEnabled(false); mIsMainUserId.setEnabled(false); -- cgit v1.2.3 From a7eff41ced8b5622f6ed96a5b834677314ae7ca8 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 3 Apr 2014 01:34:35 +0200 Subject: Break a lot of stuff. Also, database redesign. Change entire database design. This introduces a lot of changes, notably all URIs and almost all projections. Some features (like key deletion) have been simply commented out for now since they need serious reconsideration. There are a couple of new TODOs marking places where more work is needed. The migration path works fine from what I tested. The old database is not deleted for now, ie, it is reimported at every start of the application making all intermediate changes transient. Tested and working (for me): - All activities in the main drawer - Multiselect and Search - ViewKeyActivity, with and without secret key available - CertifyKeyActivity - SelectSecretKeyActivity (from CertifyKeyActivity) - SelectPublicKeyActivity (from encrypt activity) What doesn't work: - Actually certifying keys (pending a TODO in ProviderHelper) - Importing keys doesn't preserve secret keys - "Encrypt to this contact" doesn't pass key - Editing keys. All controls are disabled, I'm not sure why... (is this even my fault?) - Deleting keys What I didn't test: - Key export - API stuff - Creating keys (since editing doesn't even work) --- .../keychain/pgp/PgpDecryptVerify.java | 8 +- .../sufficientlysecure/keychain/pgp/PgpHelper.java | 2 +- .../keychain/pgp/PgpImportExport.java | 4 +- .../keychain/pgp/PgpKeyHelper.java | 25 +- .../keychain/pgp/PgpSignEncrypt.java | 4 +- .../keychain/provider/KeychainContract.java | 165 ++-- .../keychain/provider/KeychainDatabase.java | 229 ++++-- .../keychain/provider/KeychainProvider.java | 846 +++++---------------- .../provider/KeychainServiceBlobDatabase.java | 2 +- .../keychain/provider/ProviderHelper.java | 413 +++------- .../keychain/remote/OpenPgpService.java | 2 +- .../keychain/service/KeychainIntentService.java | 15 +- .../keychain/service/PassphraseCacheService.java | 5 +- .../keychain/ui/CertifyKeyActivity.java | 33 +- .../keychain/ui/EditKeyActivity.java | 4 +- .../keychain/ui/EncryptAsymmetricFragment.java | 6 +- .../keychain/ui/KeyListFragment.java | 31 +- .../keychain/ui/SelectPublicKeyFragment.java | 34 +- .../keychain/ui/SelectSecretKeyFragment.java | 52 +- .../keychain/ui/SelectSecretKeyLayoutFragment.java | 15 +- .../keychain/ui/ViewKeyActivity.java | 11 +- .../keychain/ui/ViewKeyMainFragment.java | 44 +- .../keychain/ui/adapter/ViewKeyKeysAdapter.java | 6 +- .../ui/dialog/DeleteKeyDialogFragment.java | 2 + .../ui/dialog/PassphraseDialogFragment.java | 7 +- 25 files changed, 598 insertions(+), 1367 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 29255fbbe..43a1d9aab 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -239,7 +239,7 @@ public class PgpDecryptVerify { if (mEnforcedKeyId != 0) { // TODO: improve this code! get master key directly! PGPSecretKeyRing secretKeyRing = - ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, encData.getKeyID()); + ProviderHelper.getPGPSecretKeyRingWithKeyId(mContext, encData.getKeyID()); long masterKeyId = PgpKeyHelper.getMasterKey(secretKeyRing).getKeyID(); Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID()); Log.d(Constants.TAG, "enforcedKeyId: " + mEnforcedKeyId); @@ -371,7 +371,7 @@ public class PgpDecryptVerify { signatureIndex = i; signatureKeyId = signature.getKeyID(); String userId = null; - PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId( + PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId( mContext, signatureKeyId); if (signKeyRing != null) { userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); @@ -555,7 +555,7 @@ public class PgpDecryptVerify { } else { signatureKeyId = signature.getKeyID(); String userId = null; - PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(mContext, + PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(mContext, signatureKeyId); if (signKeyRing != null) { userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); @@ -619,7 +619,7 @@ public class PgpDecryptVerify { long signatureKeyId = signature.getKeyID(); boolean validKeyBinding = false; - PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(context, + PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(context, signatureKeyId); PGPPublicKey mKey = null; if (signKeyRing != null) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java index cc40afbac..60967a0d1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java @@ -97,7 +97,7 @@ public class PgpHelper { if (obj instanceof PGPPublicKeyEncryptedData) { gotAsymmetricEncryption = true; PGPPublicKeyEncryptedData pbe = (PGPPublicKeyEncryptedData) obj; - secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, pbe.getKeyID()); + secretKey = ProviderHelper.getPGPSecretKeyRing(context, pbe.getKeyID()).getSecretKey(); if (secretKey != null) { break; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index 0e0fdec83..e2ea91470 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -184,7 +184,7 @@ public class PgpImportExport { updateProgress(progress * 100 / masterKeyIdsSize, 100); PGPPublicKeyRing publicKeyRing = - ProviderHelper.getPGPPublicKeyRingByMasterKeyId(mContext, pubKeyMasterId); + ProviderHelper.getPGPPublicKeyRing(mContext, pubKeyMasterId); if (publicKeyRing != null) { publicKeyRing.encode(arOutStream); @@ -207,7 +207,7 @@ public class PgpImportExport { updateProgress(progress * 100 / masterKeyIdsSize, 100); PGPSecretKeyRing secretKeyRing = - ProviderHelper.getPGPSecretKeyRingByMasterKeyId(mContext, secretKeyMasterId); + ProviderHelper.getPGPSecretKeyRing(mContext, secretKeyMasterId); if (secretKeyRing != null) { secretKeyRing.encode(arOutStream); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index b4bf0747f..658b9460b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -219,8 +219,7 @@ public class PgpKeyHelper { } public static PGPPublicKey getEncryptPublicKey(Context context, long masterKeyId) { - PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(context, - masterKeyId); + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRing(context, masterKeyId); if (keyRing == null) { Log.e(Constants.TAG, "keyRing is null!"); return null; @@ -234,8 +233,7 @@ public class PgpKeyHelper { } public static PGPSecretKey getCertificationKey(Context context, long masterKeyId) { - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context, - masterKeyId); + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId); if (keyRing == null) { return null; } @@ -247,8 +245,7 @@ public class PgpKeyHelper { } public static PGPSecretKey getSigningKey(Context context, long masterKeyId) { - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context, - masterKeyId); + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId); if (keyRing == null) { return null; } @@ -491,21 +488,6 @@ public class PgpKeyHelper { return algorithmStr + ", " + keySize + " bit"; } - public static String getFingerPrint(Context context, long keyId) { - PGPPublicKey key = ProviderHelper.getPGPPublicKeyByKeyId(context, keyId); - // if it is no public key get it from your own keys... - if (key == null) { - PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, keyId); - if (secretKey == null) { - Log.e(Constants.TAG, "Key could not be found!"); - return null; - } - key = secretKey.getPublicKey(); - } - - return convertFingerprintToHex(key.getFingerprint()); - } - /** * Converts fingerprint to hex (optional: with whitespaces after 4 characters) *

        @@ -513,7 +495,6 @@ public class PgpKeyHelper { * better differentiate between numbers and letters when letters are lowercase. * * @param fingerprint - * @param split split into 4 character chunks * @return */ public static String convertFingerprintToHex(byte[] fingerprint) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java index 6d80c154b..a16ebdab8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -214,7 +214,7 @@ public class PgpSignEncrypt { PGPSecretKeyRing signingKeyRing = null; PGPPrivateKey signaturePrivateKey = null; if (enableSignature) { - signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, mSignatureKeyId); + signingKeyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(mContext, mSignatureKeyId); signingKey = PgpKeyHelper.getSigningKey(mContext, mSignatureKeyId); if (signingKey == null) { throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); @@ -444,7 +444,7 @@ public class PgpSignEncrypt { } PGPSecretKeyRing signingKeyRing = - ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, mSignatureKeyId); + ProviderHelper.getPGPSecretKeyRingWithKeyId(mContext, mSignatureKeyId); PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(mContext, mSignatureKeyId); if (signingKey == null) { throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index e7b31bf65..fcf8f7962 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -26,32 +26,32 @@ public class KeychainContract { interface KeyRingsColumns { String MASTER_KEY_ID = "master_key_id"; // not a database id - String TYPE = "type"; // see KeyTypes String KEY_RING_DATA = "key_ring_data"; // PGPPublicKeyRing / PGPSecretKeyRing blob } interface KeysColumns { + String MASTER_KEY_ID = "master_key_id"; // not a database id + String RANK = "rank"; + String KEY_ID = "key_id"; // not a database id - String TYPE = "type"; // see KeyTypes - String IS_MASTER_KEY = "is_master_key"; String ALGORITHM = "algorithm"; + String FINGERPRINT = "fingerprint"; + String KEY_SIZE = "key_size"; - String CAN_CERTIFY = "can_certify"; String CAN_SIGN = "can_sign"; String CAN_ENCRYPT = "can_encrypt"; + String CAN_CERTIFY = "can_certify"; String IS_REVOKED = "is_revoked"; + String CREATION = "creation"; String EXPIRY = "expiry"; - String KEY_RING_ROW_ID = "key_ring_row_id"; // foreign key to key_rings._ID - String KEY_DATA = "key_data"; // PGPPublicKey/PGPSecretKey blob - String RANK = "rank"; - String FINGERPRINT = "fingerprint"; } interface UserIdsColumns { - String KEY_RING_ROW_ID = "key_ring_row_id"; // foreign key to key_rings._ID + String MASTER_KEY_ID = "master_key_id"; // foreign key to key_rings._ID String USER_ID = "user_id"; // not a database id - String RANK = "rank"; + String RANK = "rank"; // ONLY used for sorting! no key, no nothing! + String IS_PRIMARY = "is_primary"; } interface ApiAppsColumns { @@ -81,14 +81,15 @@ public class KeychainContract { public static final String BASE_KEY_RINGS = "key_rings"; public static final String BASE_DATA = "data"; - public static final String PATH_PUBLIC = "public"; - public static final String PATH_SECRET = "secret"; + public static final String PATH_UNIFIED = "unified"; public static final String PATH_BY_MASTER_KEY_ID = "master_key_id"; public static final String PATH_BY_KEY_ID = "key_id"; public static final String PATH_BY_EMAILS = "emails"; public static final String PATH_BY_LIKE_EMAIL = "like_email"; + public static final String PATH_PUBLIC = "public"; + public static final String PATH_SECRET = "secret"; public static final String PATH_USER_IDS = "user_ids"; public static final String PATH_KEYS = "keys"; @@ -102,72 +103,43 @@ public class KeychainContract { /** * Use if multiple items get returned */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.key_ring"; + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.key_ring"; /** * Use if a single item is returned */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.key_ring"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.key_ring"; public static Uri buildUnifiedKeyRingsUri() { - return CONTENT_URI; - } - - public static Uri buildPublicKeyRingsUri() { - return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).build(); - } - - public static Uri buildPublicKeyRingsUri(String keyRingRowId) { - return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(keyRingRowId).build(); - } - - public static Uri buildPublicKeyRingsByMasterKeyIdUri(String masterKeyId) { - return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC) - .appendPath(PATH_BY_MASTER_KEY_ID).appendPath(masterKeyId).build(); - } - - public static Uri buildPublicKeyRingsByKeyIdUri(String keyId) { - return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(PATH_BY_KEY_ID) - .appendPath(keyId).build(); + return CONTENT_URI.buildUpon().appendPath(PATH_UNIFIED).build(); } - - public static Uri buildPublicKeyRingsByEmailsUri(String emails) { - return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(PATH_BY_EMAILS) - .appendPath(emails).build(); + public static Uri buildUnifiedKeyRingsByEmailUri(String email) { + return CONTENT_URI.buildUpon().appendPath("email:" + email).build(); } - public static Uri buildPublicKeyRingsByLikeEmailUri(String emails) { - return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(PATH_BY_LIKE_EMAIL) - .appendPath(emails).build(); + public static Uri buildGenericKeyRingUri(String masterKeyId) { + return CONTENT_URI.buildUpon().appendPath(masterKeyId).build(); } - public static Uri buildSecretKeyRingsUri() { - return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).build(); + public static Uri buildPublicKeyRingUri(String masterKeyId) { + return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_PUBLIC).build(); } - - public static Uri buildSecretKeyRingsUri(String keyRingRowId) { - return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(keyRingRowId).build(); + public static Uri buildPublicKeyRingUri(Uri uri) { + return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_PUBLIC).build(); } - public static Uri buildSecretKeyRingsByMasterKeyIdUri(String masterKeyId) { - return CONTENT_URI.buildUpon().appendPath(PATH_SECRET) - .appendPath(PATH_BY_MASTER_KEY_ID).appendPath(masterKeyId).build(); + public static Uri buildSecretKeyRingUri(String masterKeyId) { + return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_SECRET).build(); } - - public static Uri buildSecretKeyRingsByKeyIdUri(String keyId) { - return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(PATH_BY_KEY_ID) - .appendPath(keyId).build(); + public static Uri buildSecretKeyRingUri(Uri uri) { + return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_SECRET).build(); } - public static Uri buildSecretKeyRingsByEmailsUri(String emails) { - // TODO: encoded? - return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(PATH_BY_EMAILS) - .appendPath(emails).build(); + public static Uri buildUnifiedKeyRingUri(String masterKeyId) { + return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_UNIFIED).build(); } - - public static Uri buildSecretKeyRingsByLikeEmails(String emails) { - return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(PATH_BY_LIKE_EMAIL) - .appendPath(emails).build(); + public static Uri buildUnifiedKeyRingUri(Uri uri) { + return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_UNIFIED).build(); } } @@ -178,40 +150,20 @@ public class KeychainContract { /** * Use if multiple items get returned */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.key"; + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.key"; /** * Use if a single item is returned */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.key"; - - public static Uri buildPublicKeysUri(String keyRingRowId) { - return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(keyRingRowId) - .appendPath(PATH_KEYS).build(); - } - - public static Uri buildPublicKeysUri(String keyRingRowId, String keyRowId) { - return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(keyRingRowId) - .appendPath(PATH_KEYS).appendPath(keyRowId).build(); - } - - public static Uri buildSecretKeysUri(String keyRingRowId) { - return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(keyRingRowId) - .appendPath(PATH_KEYS).build(); - } + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.key"; - public static Uri buildSecretKeysUri(String keyRingRowId, String keyRowId) { - return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(keyRingRowId) - .appendPath(PATH_KEYS).appendPath(keyRowId).build(); + public static Uri buildKeysUri(String masterKeyId) { + return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_KEYS).build(); } - - public static Uri buildKeysUri(Uri keyRingUri) { - return keyRingUri.buildUpon().appendPath(PATH_KEYS).build(); + public static Uri buildKeysUri(Uri uri) { + return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_KEYS).build(); } - public static Uri buildKeysUri(Uri keyRingUri, String keyRowId) { - return keyRingUri.buildUpon().appendPath(PATH_KEYS).appendPath(keyRowId).build(); - } } public static class UserIds implements UserIdsColumns, BaseColumns { @@ -221,39 +173,18 @@ public class KeychainContract { /** * Use if multiple items get returned */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.user_id"; + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.user_id"; /** * Use if a single item is returned */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.user_id"; - - public static Uri buildPublicUserIdsUri(String keyRingRowId) { - return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(keyRingRowId) - .appendPath(PATH_USER_IDS).build(); - } - - public static Uri buildPublicUserIdsUri(String keyRingRowId, String userIdRowId) { - return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(keyRingRowId) - .appendPath(PATH_USER_IDS).appendPath(userIdRowId).build(); - } + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.user_id"; - public static Uri buildSecretUserIdsUri(String keyRingRowId) { - return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(keyRingRowId) - .appendPath(PATH_USER_IDS).build(); + public static Uri buildUserIdsUri(String masterKeyId) { + return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_USER_IDS).build(); } - - public static Uri buildSecretUserIdsUri(String keyRingRowId, String userIdRowId) { - return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(keyRingRowId) - .appendPath(PATH_USER_IDS).appendPath(userIdRowId).build(); - } - - public static Uri buildUserIdsUri(Uri keyRingUri) { - return keyRingUri.buildUpon().appendPath(PATH_USER_IDS).build(); - } - - public static Uri buildUserIdsUri(Uri keyRingUri, String userIdRowId) { - return keyRingUri.buildUpon().appendPath(PATH_USER_IDS).appendPath(userIdRowId).build(); + public static Uri buildUserIdsUri(Uri uri) { + return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_USER_IDS).build(); } } @@ -264,12 +195,12 @@ public class KeychainContract { /** * Use if multiple items get returned */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api_apps"; + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.api_apps"; /** * Use if a single item is returned */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_app"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.api_app"; public static Uri buildByPackageNameUri(String packageName) { return CONTENT_URI.buildUpon().appendEncodedPath(packageName).build(); @@ -283,12 +214,12 @@ public class KeychainContract { /** * Use if multiple items get returned */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api_app.accounts"; + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.api_app.accounts"; /** * Use if a single item is returned */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_app.account"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.api_app.account"; public static Uri buildBaseUri(String packageName) { return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS) diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 8c33844b2..055957eda 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -18,11 +18,16 @@ package org.sufficientlysecure.keychain.provider; import android.content.Context; +import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.provider.BaseColumns; +import org.spongycastle.openpgp.PGPKeyRing; +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPSecretKeyRing; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns; @@ -30,51 +35,72 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns; import org.sufficientlysecure.keychain.util.Log; +import java.io.IOException; +import java.util.Arrays; + public class KeychainDatabase extends SQLiteOpenHelper { - private static final String DATABASE_NAME = "apg.db"; - private static final int DATABASE_VERSION = 8; + private static final String DATABASE_NAME = "openkeychain.db"; + private static final int DATABASE_VERSION = 1; + static Boolean apg_hack = false; public interface Tables { - String KEY_RINGS = "key_rings"; + String KEY_RINGS_PUBLIC = "keyrings_public"; + String KEY_RINGS_SECRET = "keyrings_secret"; String KEYS = "keys"; String USER_IDS = "user_ids"; String API_APPS = "api_apps"; String API_ACCOUNTS = "api_accounts"; } - private static final String CREATE_KEY_RINGS = "CREATE TABLE IF NOT EXISTS " + Tables.KEY_RINGS - + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " - + KeyRingsColumns.MASTER_KEY_ID + " INT64, " - + KeyRingsColumns.TYPE + " INTEGER, " - + KeyRingsColumns.KEY_RING_DATA + " BLOB)"; - - private static final String CREATE_KEYS = "CREATE TABLE IF NOT EXISTS " + Tables.KEYS + " (" - + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " - + KeysColumns.KEY_ID + " INT64, " - + KeysColumns.TYPE + " INTEGER, " - + KeysColumns.IS_MASTER_KEY + " INTEGER, " - + KeysColumns.ALGORITHM + " INTEGER, " - + KeysColumns.KEY_SIZE + " INTEGER, " - + KeysColumns.CAN_CERTIFY + " INTEGER, " - + KeysColumns.CAN_SIGN + " INTEGER, " - + KeysColumns.CAN_ENCRYPT + " INTEGER, " - + KeysColumns.IS_REVOKED + " INTEGER, " - + KeysColumns.CREATION + " INTEGER, " - + KeysColumns.EXPIRY + " INTEGER, " - + KeysColumns.KEY_DATA + " BLOB," - + KeysColumns.RANK + " INTEGER, " - + KeysColumns.FINGERPRINT + " BLOB, " - + KeysColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, " - + "FOREIGN KEY(" + KeysColumns.KEY_RING_ROW_ID + ") REFERENCES " - + Tables.KEY_RINGS + "(" + BaseColumns._ID + ") ON DELETE CASCADE)"; - - private static final String CREATE_USER_IDS = "CREATE TABLE IF NOT EXISTS " + Tables.USER_IDS - + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " - + UserIdsColumns.USER_ID + " TEXT, " - + UserIdsColumns.RANK + " INTEGER, " - + UserIdsColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, " - + "FOREIGN KEY(" + UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES " - + Tables.KEY_RINGS + "(" + BaseColumns._ID + ") ON DELETE CASCADE)"; + private static final String CREATE_KEYRINGS_PUBLIC = + "CREATE TABLE IF NOT EXISTS keyrings_public (" + + KeyRingsColumns.MASTER_KEY_ID + " INTEGER PRIMARY KEY," + + KeyRingsColumns.KEY_RING_DATA + " BLOB" + + ")"; + + private static final String CREATE_KEYRINGS_SECRET = + "CREATE TABLE IF NOT EXISTS keyrings_secret (" + + KeyRingsColumns.MASTER_KEY_ID + " INTEGER PRIMARY KEY," + + KeyRingsColumns.KEY_RING_DATA + " BLOB," + + "FOREIGN KEY(" + KeyRingsColumns.MASTER_KEY_ID + ") " + + "REFERENCES keyrings_public(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE" + + ")"; + + private static final String CREATE_KEYS = + "CREATE TABLE IF NOT EXISTS " + Tables.KEYS + " (" + + KeysColumns.MASTER_KEY_ID + " INTEGER, " + + KeysColumns.RANK + " INTEGER, " + + + KeysColumns.KEY_ID + " INTEGER, " + + KeysColumns.KEY_SIZE + " INTEGER, " + + KeysColumns.ALGORITHM + " INTEGER, " + + KeysColumns.FINGERPRINT + " BLOB, " + + + KeysColumns.CAN_CERTIFY + " BOOLEAN, " + + KeysColumns.CAN_SIGN + " BOOLEAN, " + + KeysColumns.CAN_ENCRYPT + " BOOLEAN, " + + KeysColumns.IS_REVOKED + " BOOLEAN, " + + + KeysColumns.CREATION + " INTEGER, " + + KeysColumns.EXPIRY + " INTEGER, " + + + "PRIMARY KEY(" + KeysColumns.MASTER_KEY_ID + ", " + KeysColumns.RANK + ")," + + "FOREIGN KEY(" + KeysColumns.MASTER_KEY_ID + ") REFERENCES " + + Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE" + + ")"; + + private static final String CREATE_USER_IDS = + "CREATE TABLE IF NOT EXISTS " + Tables.USER_IDS + "(" + + UserIdsColumns.MASTER_KEY_ID + " INTEGER, " + + UserIdsColumns.USER_ID + " CHARMANDER, " + + + UserIdsColumns.IS_PRIMARY + " BOOLEAN, " + + UserIdsColumns.RANK+ " INTEGER, " + + + "PRIMARY KEY(" + UserIdsColumns.MASTER_KEY_ID + ", " + UserIdsColumns.USER_ID + ")," + + "FOREIGN KEY(" + UserIdsColumns.MASTER_KEY_ID + ") REFERENCES " + + Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE" + + ")"; private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " @@ -96,13 +122,27 @@ public class KeychainDatabase extends SQLiteOpenHelper { KeychainDatabase(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); + + + // make sure this is only done once, on the first instance! + boolean iAmIt = false; + synchronized(apg_hack) { + if(!apg_hack) { + iAmIt = true; + apg_hack = true; + } + } + // if it's us, do the import + if(iAmIt) + checkAndImportApg(context); } @Override public void onCreate(SQLiteDatabase db) { Log.w(Constants.TAG, "Creating database..."); - db.execSQL(CREATE_KEY_RINGS); + db.execSQL(CREATE_KEYRINGS_PUBLIC); + db.execSQL(CREATE_KEYRINGS_SECRET); db.execSQL(CREATE_KEYS); db.execSQL(CREATE_USER_IDS); db.execSQL(CREATE_API_APPS); @@ -119,44 +159,91 @@ public class KeychainDatabase extends SQLiteOpenHelper { } @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - Log.w(Constants.TAG, "Upgrading database from version " + oldVersion + " to " + newVersion); - - // Upgrade from oldVersion through all cases to newest one - for (int version = oldVersion; version < newVersion; ++version) { - Log.w(Constants.TAG, "Upgrading database to version " + version); - - switch (version) { - case 3: - db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.CAN_CERTIFY - + " INTEGER DEFAULT 0;"); - db.execSQL("UPDATE " + Tables.KEYS + " SET " + KeysColumns.CAN_CERTIFY - + " = 1 WHERE " + KeysColumns.IS_MASTER_KEY + "= 1;"); - break; - case 4: - db.execSQL(CREATE_API_APPS); - break; - case 5: - // new column: package_signature - db.execSQL("DROP TABLE IF EXISTS " + Tables.API_APPS); - db.execSQL(CREATE_API_APPS); - break; - case 6: - // new column: fingerprint - db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.FINGERPRINT - + " BLOB;"); - break; - case 7: - // new db layout for api apps - db.execSQL("DROP TABLE IF EXISTS " + Tables.API_APPS); - db.execSQL(CREATE_API_APPS); - db.execSQL(CREATE_API_APPS_ACCOUNTS); - break; - default: + public void onUpgrade(SQLiteDatabase db, int old, int nu) { + // don't care (this is version 1) + } + + /** This method tries to import data from a provided database. + * + * The sole assumptions made on this db are that there is a key_rings table + * with a key_ring_data and a type column, the latter of which should be bigger + * for secret keys. + */ + public void checkAndImportApg(Context context) { + + boolean hasApgDb = false; { + // It's the Java way =( + String[] dbs = context.databaseList(); + for(String db : dbs) { + if(db.equals("apg.db")) { + hasApgDb = true; break; + } + } + } + + if(!hasApgDb) + return; + + Log.d(Constants.TAG, "apg.db exists! Importing..."); + SQLiteDatabase db = new SQLiteOpenHelper(context, "apg.db", null, 1) { + @Override + public void onCreate(SQLiteDatabase db) { + // should never happen + assert false; } + @Override + public void onDowngrade(SQLiteDatabase db, int old, int nu) { + // don't care + } + @Override + public void onUpgrade(SQLiteDatabase db, int old, int nu) { + // don't care either + } + }.getReadableDatabase(); + + // kill current! + { // TODO don't kill current. + Log.d(Constants.TAG, "Truncating db..."); + SQLiteDatabase d = getWritableDatabase(); + d.execSQL("DELETE FROM keyrings_public"); + d.close(); + Log.d(Constants.TAG, "Ok."); } + + Cursor c = db.rawQuery("SELECT key_ring_data FROM key_rings ORDER BY type ASC", null); + try { + // import from old database + Log.d(Constants.TAG, "Importing " + c.getCount() + " keyrings from apg.db..."); + for(int i = 0; i < c.getCount(); i++) { + c.moveToPosition(i); + byte[] data = c.getBlob(0); + PGPKeyRing ring = PgpConversionHelper.BytesToPGPKeyRing(data); + if(ring instanceof PGPPublicKeyRing) + ProviderHelper.saveKeyRing(context, (PGPPublicKeyRing) ring); + else if(ring instanceof PGPSecretKeyRing) + ProviderHelper.saveKeyRing(context, (PGPSecretKeyRing) ring); + else { + Log.e(Constants.TAG, "Unknown blob data type!"); + } + } + + } catch(IOException e) { + Log.e(Constants.TAG, "Error importing apg db!", e); + return; + } finally { + if(c != null) + c.close(); + if(db != null) + db.close(); + } + + // TODO delete old db, if we are sure this works + // context.deleteDatabase("apg.db"); + Log.d(Constants.TAG, "All done, (not) deleting apg.db"); + + } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 1c5e3ab36..39ea083fa 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -52,40 +52,19 @@ public class KeychainProvider extends ContentProvider { // public static final String EXTRA_BROADCAST_KEY_TYPE = "key_type"; // public static final String EXTRA_BROADCAST_CONTENT_ITEM_TYPE = "contentItemType"; - private static final int PUBLIC_KEY_RING = 101; - private static final int PUBLIC_KEY_RING_BY_ROW_ID = 102; - private static final int PUBLIC_KEY_RING_BY_MASTER_KEY_ID = 103; - private static final int PUBLIC_KEY_RING_BY_KEY_ID = 104; - private static final int PUBLIC_KEY_RING_BY_EMAILS = 105; - private static final int PUBLIC_KEY_RING_BY_LIKE_EMAIL = 106; + private static final int KEY_RINGS_UNIFIED = 101; - private static final int PUBLIC_KEY_RING_KEY = 111; - private static final int PUBLIC_KEY_RING_KEY_BY_ROW_ID = 112; - - private static final int PUBLIC_KEY_RING_USER_ID = 121; - private static final int PUBLIC_KEY_RING_USER_ID_BY_ROW_ID = 122; - private static final int PUBLIC_KEY_RING_BY_MASTER_KEY_ID_USER_ID = 123; - - private static final int SECRET_KEY_RING = 201; - private static final int SECRET_KEY_RING_BY_ROW_ID = 202; - private static final int SECRET_KEY_RING_BY_MASTER_KEY_ID = 203; - private static final int SECRET_KEY_RING_BY_KEY_ID = 204; - private static final int SECRET_KEY_RING_BY_EMAILS = 205; - private static final int SECRET_KEY_RING_BY_LIKE_EMAIL = 206; - - private static final int SECRET_KEY_RING_KEY = 211; - private static final int SECRET_KEY_RING_KEY_BY_ROW_ID = 212; - - private static final int SECRET_KEY_RING_USER_ID = 221; - private static final int SECRET_KEY_RING_USER_ID_BY_ROW_ID = 222; + private static final int KEY_RING_UNIFIED = 200; + private static final int KEY_RING_KEYS = 201; + private static final int KEY_RING_USER_IDS = 202; + private static final int KEY_RING_PUBLIC = 203; + private static final int KEY_RING_SECRET = 204; private static final int API_APPS = 301; private static final int API_APPS_BY_PACKAGE_NAME = 303; private static final int API_ACCOUNTS = 304; private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 306; - private static final int UNIFIED_KEY_RING = 401; - // private static final int DATA_STREAM = 401; protected UriMatcher mUriMatcher; @@ -100,142 +79,42 @@ public class KeychainProvider extends ContentProvider { String authority = KeychainContract.CONTENT_AUTHORITY; /** - * unified key rings - * - *

        -         * key_rings
        -         * 
        - */ - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS, UNIFIED_KEY_RING); - - /** - * public key rings - * - *
        -         * key_rings/public
        -         * key_rings/public/#
        -         * key_rings/public/master_key_id/_
        -         * key_rings/public/key_id/_
        -         * key_rings/public/emails/_
        -         * key_rings/public/like_email/_
        -         * 
        - */ - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_PUBLIC, PUBLIC_KEY_RING); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_PUBLIC + "/#", PUBLIC_KEY_RING_BY_ROW_ID); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_MASTER_KEY_ID - + "/*", PUBLIC_KEY_RING_BY_MASTER_KEY_ID); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_KEY_ID + "/*", - PUBLIC_KEY_RING_BY_KEY_ID); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_EMAILS + "/*", - PUBLIC_KEY_RING_BY_EMAILS); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_EMAILS, - PUBLIC_KEY_RING_BY_EMAILS); // without emails specified - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_LIKE_EMAIL + "/*", - PUBLIC_KEY_RING_BY_LIKE_EMAIL); - - /** - * public keys - * - *
        -         * key_rings/public/#/keys
        -         * key_rings/public/#/keys/#
        -         * 
        - */ - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_PUBLIC + "/#/" + KeychainContract.PATH_KEYS, - PUBLIC_KEY_RING_KEY); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_PUBLIC + "/#/" + KeychainContract.PATH_KEYS + "/#", - PUBLIC_KEY_RING_KEY_BY_ROW_ID); - - /** - * public user ids - * - *
        -         * key_rings/public/#/user_ids
        -         * key_rings/public/#/user_ids/#
        -         * key_rings/public/master_key_id/#/user_ids
        -         * 
        - */ - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_PUBLIC + "/#/" + KeychainContract.PATH_USER_IDS, - PUBLIC_KEY_RING_USER_ID); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_PUBLIC + "/#/" + KeychainContract.PATH_USER_IDS + "/#", - PUBLIC_KEY_RING_USER_ID_BY_ROW_ID); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_PUBLIC + "/" - + KeychainContract.PATH_BY_MASTER_KEY_ID + "/*/" + KeychainContract.PATH_USER_IDS, - PUBLIC_KEY_RING_BY_MASTER_KEY_ID_USER_ID); - - /** - * secret key rings + * select from key_ring * *
        -         * key_rings/secret
        -         * key_rings/secret/#
        -         * key_rings/secret/master_key_id/_
        -         * key_rings/secret/key_id/_
        -         * key_rings/secret/emails/_
        -         * key_rings/secret/like_email/_
        +         * key_rings/unified
                  * 
        */ - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_SECRET, SECRET_KEY_RING); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_SECRET + "/#", SECRET_KEY_RING_BY_ROW_ID); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_MASTER_KEY_ID - + "/*", SECRET_KEY_RING_BY_MASTER_KEY_ID); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_KEY_ID + "/*", - SECRET_KEY_RING_BY_KEY_ID); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_EMAILS + "/*", - SECRET_KEY_RING_BY_EMAILS); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_EMAILS, - SECRET_KEY_RING_BY_EMAILS); // without emails specified - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_LIKE_EMAIL + "/*", - SECRET_KEY_RING_BY_LIKE_EMAIL); + matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + + "/" + KeychainContract.PATH_UNIFIED, + KEY_RINGS_UNIFIED); /** - * secret keys + * select from key_ring * *
        -         * key_rings/secret/#/keys
        -         * key_rings/secret/#/keys/#
        +         * key_rings/_/unified
        +         * key_rings/_/keys
        +         * key_rings/_/user_ids
        +         * key_rings/_/public
        +         * key_rings/_/secret
                  * 
        */ - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_SECRET + "/#/" + KeychainContract.PATH_KEYS, - SECRET_KEY_RING_KEY); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_SECRET + "/#/" + KeychainContract.PATH_KEYS + "/#", - SECRET_KEY_RING_KEY_BY_ROW_ID); - - /** - * secret user ids - * - *
        -         * key_rings/secret/#/user_ids
        -         * key_rings/secret/#/user_ids/#
        -         * 
        - */ - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_SECRET + "/#/" + KeychainContract.PATH_USER_IDS, - SECRET_KEY_RING_USER_ID); - matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" - + KeychainContract.PATH_SECRET + "/#/" + KeychainContract.PATH_USER_IDS + "/#", - SECRET_KEY_RING_USER_ID_BY_ROW_ID); + matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/" + + KeychainContract.PATH_UNIFIED, + KEY_RING_UNIFIED); + matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/" + + KeychainContract.PATH_KEYS, + KEY_RING_KEYS); + matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/" + + KeychainContract.PATH_USER_IDS, + KEY_RING_USER_IDS); + matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/" + + KeychainContract.PATH_PUBLIC, + KEY_RING_PUBLIC); + matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/" + + KeychainContract.PATH_SECRET, + KEY_RING_SECRET); /** * API apps @@ -287,38 +166,17 @@ public class KeychainProvider extends ContentProvider { public String getType(Uri uri) { final int match = mUriMatcher.match(uri); switch (match) { - case PUBLIC_KEY_RING: - case PUBLIC_KEY_RING_BY_EMAILS: - case PUBLIC_KEY_RING_BY_LIKE_EMAIL: - case SECRET_KEY_RING: - case SECRET_KEY_RING_BY_EMAILS: - case SECRET_KEY_RING_BY_LIKE_EMAIL: - return KeyRings.CONTENT_TYPE; - - case PUBLIC_KEY_RING_BY_ROW_ID: - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: - case PUBLIC_KEY_RING_BY_KEY_ID: - case SECRET_KEY_RING_BY_ROW_ID: - case SECRET_KEY_RING_BY_MASTER_KEY_ID: - case SECRET_KEY_RING_BY_KEY_ID: + case KEY_RING_PUBLIC: return KeyRings.CONTENT_ITEM_TYPE; - case PUBLIC_KEY_RING_KEY: - case SECRET_KEY_RING_KEY: + case KEY_RING_KEYS: return Keys.CONTENT_TYPE; - case PUBLIC_KEY_RING_KEY_BY_ROW_ID: - case SECRET_KEY_RING_KEY_BY_ROW_ID: - return Keys.CONTENT_ITEM_TYPE; - - case PUBLIC_KEY_RING_USER_ID: - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID_USER_ID: - case SECRET_KEY_RING_USER_ID: + case KEY_RING_USER_IDS: return UserIds.CONTENT_TYPE; - case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: - case SECRET_KEY_RING_USER_ID_BY_ROW_ID: - return UserIds.CONTENT_ITEM_TYPE; + case KEY_RING_SECRET: + return KeyRings.CONTENT_ITEM_TYPE; case API_APPS: return ApiApps.CONTENT_TYPE; @@ -337,175 +195,9 @@ public class KeychainProvider extends ContentProvider { } } - /** - * Returns type of the query (secret/public) - * - * @param match - * @return - */ - private int getKeyType(int match) { - int type; - switch (match) { - case PUBLIC_KEY_RING: - case PUBLIC_KEY_RING_BY_ROW_ID: - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: - case PUBLIC_KEY_RING_BY_KEY_ID: - case PUBLIC_KEY_RING_BY_EMAILS: - case PUBLIC_KEY_RING_BY_LIKE_EMAIL: - case PUBLIC_KEY_RING_KEY: - case PUBLIC_KEY_RING_KEY_BY_ROW_ID: - case PUBLIC_KEY_RING_USER_ID: - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID_USER_ID: - case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: - type = KeyTypes.PUBLIC; - break; - - case SECRET_KEY_RING: - case SECRET_KEY_RING_BY_ROW_ID: - case SECRET_KEY_RING_BY_MASTER_KEY_ID: - case SECRET_KEY_RING_BY_KEY_ID: - case SECRET_KEY_RING_BY_EMAILS: - case SECRET_KEY_RING_BY_LIKE_EMAIL: - case SECRET_KEY_RING_KEY: - case SECRET_KEY_RING_KEY_BY_ROW_ID: - case SECRET_KEY_RING_USER_ID: - case SECRET_KEY_RING_USER_ID_BY_ROW_ID: - type = KeyTypes.SECRET; - break; - - default: - Log.e(Constants.TAG, "Unknown match " + match); - type = -1; - break; - } - - return type; - } - - /** - * Set result of query to specific columns, don't show blob column - * - * @return - */ - private HashMap getProjectionMapForKeyRings() { - HashMap projectionMap = new HashMap(); - - projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID); - projectionMap.put(KeyRingsColumns.KEY_RING_DATA, Tables.KEY_RINGS + "." - + KeyRingsColumns.KEY_RING_DATA); - projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." - + KeyRingsColumns.MASTER_KEY_ID); - // TODO: deprecated master key id - //projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEYS + "." + KeysColumns.KEY_ID); - - projectionMap.put(KeysColumns.ALGORITHM, Tables.KEYS + "." + KeysColumns.ALGORITHM); - projectionMap.put(KeysColumns.KEY_SIZE, Tables.KEYS + "." + KeysColumns.KEY_SIZE); - projectionMap.put(KeysColumns.CREATION, Tables.KEYS + "." + KeysColumns.CREATION); - projectionMap.put(KeysColumns.EXPIRY, Tables.KEYS + "." + KeysColumns.EXPIRY); - projectionMap.put(KeysColumns.KEY_RING_ROW_ID, Tables.KEYS + "." + KeysColumns.KEY_RING_ROW_ID); - projectionMap.put(KeysColumns.FINGERPRINT, Tables.KEYS + "." + KeysColumns.FINGERPRINT); - projectionMap.put(KeysColumns.IS_REVOKED, Tables.KEYS + "." + KeysColumns.IS_REVOKED); - - projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + UserIdsColumns.USER_ID); - - // type attribute is special: if there is any grouping, choose secret over public type - projectionMap.put(KeyRingsColumns.TYPE, - "MAX(" + Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + ") AS " + KeyRingsColumns.TYPE); - - return projectionMap; - } - - /** - * Set result of query to specific columns, don't show blob column - * - * @return - */ - private HashMap getProjectionMapForKeys() { - HashMap projectionMap = new HashMap(); - - projectionMap.put(BaseColumns._ID, BaseColumns._ID); - projectionMap.put(KeysColumns.KEY_ID, KeysColumns.KEY_ID); - projectionMap.put(KeysColumns.IS_MASTER_KEY, KeysColumns.IS_MASTER_KEY); - projectionMap.put(KeysColumns.ALGORITHM, KeysColumns.ALGORITHM); - projectionMap.put(KeysColumns.KEY_SIZE, KeysColumns.KEY_SIZE); - projectionMap.put(KeysColumns.CAN_CERTIFY, KeysColumns.CAN_CERTIFY); - projectionMap.put(KeysColumns.CAN_SIGN, KeysColumns.CAN_SIGN); - projectionMap.put(KeysColumns.CAN_ENCRYPT, KeysColumns.CAN_ENCRYPT); - projectionMap.put(KeysColumns.IS_REVOKED, KeysColumns.IS_REVOKED); - projectionMap.put(KeysColumns.CREATION, KeysColumns.CREATION); - projectionMap.put(KeysColumns.EXPIRY, KeysColumns.EXPIRY); - projectionMap.put(KeysColumns.KEY_RING_ROW_ID, KeysColumns.KEY_RING_ROW_ID); - projectionMap.put(KeysColumns.KEY_DATA, KeysColumns.KEY_DATA); - projectionMap.put(KeysColumns.RANK, KeysColumns.RANK); - projectionMap.put(KeysColumns.FINGERPRINT, KeysColumns.FINGERPRINT); - - return projectionMap; - } - - private HashMap getProjectionMapForUserIds() { - HashMap projectionMap = new HashMap(); - - projectionMap.put(BaseColumns._ID, Tables.USER_IDS + "." + BaseColumns._ID); - projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + UserIdsColumns.USER_ID); - projectionMap.put(UserIdsColumns.RANK, Tables.USER_IDS + "." + UserIdsColumns.RANK); - projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." - + KeyRingsColumns.MASTER_KEY_ID); - - return projectionMap; - } - - /** - * Builds default query for keyRings: KeyRings table is joined with UserIds and Keys - */ - private SQLiteQueryBuilder buildKeyRingQuery(SQLiteQueryBuilder qb, int match) { - if (match != UNIFIED_KEY_RING) { - // public or secret keyring - qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = "); - qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); - } - - // join keyrings with keys and userIds - // Only get user id and key with rank 0 (main user id and main key) - qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "(" - + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "." - + KeysColumns.KEY_RING_ROW_ID + " AND " + Tables.KEYS + "." - + KeysColumns.RANK + " = '0') " + " INNER JOIN " + Tables.USER_IDS + " ON " - + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "." - + UserIdsColumns.KEY_RING_ROW_ID + " AND " + Tables.USER_IDS + "." - + UserIdsColumns.RANK + " = '0')"); - - qb.setProjectionMap(getProjectionMapForKeyRings()); - - return qb; - } - - /** - * Builds default query for keyRings: KeyRings table is joined with UserIds and Keys - *

        - * Here only one key should be selected in the query to return a single keyring! - */ - private SQLiteQueryBuilder buildKeyRingQueryWithSpecificKey(SQLiteQueryBuilder qb, int match) { - // public or secret keyring - qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = "); - qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); - - // join keyrings with keys and userIds to every keyring - qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "(" - + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "." - + KeysColumns.KEY_RING_ROW_ID + ") " + " INNER JOIN " + Tables.USER_IDS + " ON " - + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "." - + UserIdsColumns.KEY_RING_ROW_ID + " AND " + Tables.USER_IDS + "." - + UserIdsColumns.RANK + " = '0')"); - - qb.setProjectionMap(getProjectionMapForKeyRings()); - - return qb; - } - /** * {@inheritDoc} */ - @SuppressWarnings("deprecation") @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { @@ -520,64 +212,53 @@ public class KeychainProvider extends ContentProvider { String groupBy = null, having = null; switch (match) { - case UNIFIED_KEY_RING: - qb = buildKeyRingQuery(qb, match); - - // GROUP BY so we don't get duplicates - groupBy = Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID; - - if (TextUtils.isEmpty(sortOrder)) { - sortOrder = KeyRings.TYPE + " DESC, " + - Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; + case KEY_RING_UNIFIED: + case KEY_RINGS_UNIFIED: { + HashMap projectionMap = new HashMap(); + projectionMap.put(BaseColumns._ID, Tables.KEYS + ".oid AS _id"); + projectionMap.put(KeysColumns.MASTER_KEY_ID, Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID); + projectionMap.put(KeysColumns.RANK, Tables.KEYS + "." + KeysColumns.RANK); + projectionMap.put(KeysColumns.KEY_ID, KeysColumns.KEY_ID); + projectionMap.put(KeysColumns.KEY_SIZE, KeysColumns.KEY_SIZE); + projectionMap.put(KeysColumns.IS_REVOKED, KeysColumns.IS_REVOKED); + projectionMap.put(KeysColumns.CAN_CERTIFY, KeysColumns.CAN_CERTIFY); + projectionMap.put(KeysColumns.CAN_ENCRYPT, KeysColumns.CAN_ENCRYPT); + projectionMap.put(KeysColumns.CAN_SIGN, KeysColumns.CAN_SIGN); + projectionMap.put(KeysColumns.CREATION, KeysColumns.CREATION); + projectionMap.put(KeysColumns.EXPIRY, KeysColumns.EXPIRY); + projectionMap.put(KeysColumns.ALGORITHM, KeysColumns.ALGORITHM); + projectionMap.put(KeysColumns.FINGERPRINT, KeysColumns.FINGERPRINT); + projectionMap.put(UserIdsColumns.USER_ID, UserIdsColumns.USER_ID); + projectionMap.put(Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID, Tables.KEY_RINGS_SECRET + "." + KeyRingsColumns.MASTER_KEY_ID); + qb.setProjectionMap(projectionMap); + + qb.setTables( + Tables.KEYS + + " INNER JOIN " + Tables.USER_IDS + " ON (" + + Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID + + " = " + + Tables.USER_IDS + "." + UserIdsColumns.MASTER_KEY_ID + + " AND " + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = 0" + + ") LEFT JOIN " + Tables.KEY_RINGS_SECRET + " ON (" + + Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID + + " = " + + Tables.KEY_RINGS_SECRET + "." + KeyRingsColumns.MASTER_KEY_ID + + ")" + ); + qb.appendWhere(Tables.KEYS + "." + KeysColumns.RANK + " = 0"); + + if(match == KEY_RING_UNIFIED) { + qb.appendWhere(" AND " + Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(1)); + } else if (TextUtils.isEmpty(sortOrder)) { + sortOrder = + Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + " IS NULL DESC" + + Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; } break; - case PUBLIC_KEY_RING: - case SECRET_KEY_RING: - qb = buildKeyRingQuery(qb, match); - - if (TextUtils.isEmpty(sortOrder)) { - sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; - } - - break; - case PUBLIC_KEY_RING_BY_ROW_ID: - case SECRET_KEY_RING_BY_ROW_ID: - qb = buildKeyRingQuery(qb, match); - - qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + BaseColumns._ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); - - if (TextUtils.isEmpty(sortOrder)) { - sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; - } - - break; - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: - case SECRET_KEY_RING_BY_MASTER_KEY_ID: - qb = buildKeyRingQuery(qb, match); - - qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); - - if (TextUtils.isEmpty(sortOrder)) { - sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; - } - - break; - case SECRET_KEY_RING_BY_KEY_ID: - case PUBLIC_KEY_RING_BY_KEY_ID: - qb = buildKeyRingQueryWithSpecificKey(qb, match); - - qb.appendWhere(" AND " + Tables.KEYS + "." + KeysColumns.KEY_ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); - - if (TextUtils.isEmpty(sortOrder)) { - sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; - } - - break; - case SECRET_KEY_RING_BY_EMAILS: + } + /*case SECRET_KEY_RING_BY_EMAILS: case PUBLIC_KEY_RING_BY_EMAILS: qb = buildKeyRingQuery(qb, match); @@ -603,78 +284,77 @@ public class KeychainProvider extends ContentProvider { + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID + " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + emailWhere + "))"); - } + }*/ + + case KEY_RING_KEYS: { + HashMap projectionMap = new HashMap(); + projectionMap.put(BaseColumns._ID, Tables.KEYS + ".oid AS _id"); + projectionMap.put(KeysColumns.MASTER_KEY_ID, Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID); + projectionMap.put(KeysColumns.RANK, Tables.KEYS + "." + KeysColumns.RANK); + projectionMap.put(KeysColumns.KEY_ID, KeysColumns.KEY_ID); + projectionMap.put(KeysColumns.KEY_SIZE, KeysColumns.KEY_SIZE); + projectionMap.put(KeysColumns.IS_REVOKED, KeysColumns.IS_REVOKED); + projectionMap.put(KeysColumns.CAN_CERTIFY, KeysColumns.CAN_CERTIFY); + projectionMap.put(KeysColumns.CAN_ENCRYPT, KeysColumns.CAN_ENCRYPT); + projectionMap.put(KeysColumns.CAN_SIGN, KeysColumns.CAN_SIGN); + projectionMap.put(KeysColumns.CREATION, KeysColumns.CREATION); + projectionMap.put(KeysColumns.EXPIRY, KeysColumns.EXPIRY); + projectionMap.put(KeysColumns.ALGORITHM, KeysColumns.ALGORITHM); + projectionMap.put(KeysColumns.FINGERPRINT, KeysColumns.FINGERPRINT); + qb.setProjectionMap(projectionMap); - break; - case SECRET_KEY_RING_BY_LIKE_EMAIL: - case PUBLIC_KEY_RING_BY_LIKE_EMAIL: - qb = buildKeyRingQuery(qb, match); - - String likeEmail = uri.getLastPathSegment(); - - String likeEmailWhere = "tmp." + UserIdsColumns.USER_ID + " LIKE " - + DatabaseUtils.sqlEscapeString("%<%" + likeEmail + "%>"); - - qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM " - + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID - + " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + likeEmailWhere - + "))"); + qb.setTables(Tables.KEYS); + qb.appendWhere(KeysColumns.MASTER_KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(1)); break; - case PUBLIC_KEY_RING_KEY: - case SECRET_KEY_RING_KEY: - qb.setTables(Tables.KEYS); - qb.appendWhere(KeysColumns.TYPE + " = "); - qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); + } - qb.appendWhere(" AND " + KeysColumns.KEY_RING_ROW_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + case KEY_RING_USER_IDS: { + HashMap projectionMap = new HashMap(); + projectionMap.put(BaseColumns._ID, Tables.USER_IDS + ".oid AS _id"); + projectionMap.put(UserIds.MASTER_KEY_ID, UserIds.MASTER_KEY_ID); + projectionMap.put(UserIds.USER_ID, UserIds.USER_ID); + projectionMap.put(UserIds.RANK, UserIds.RANK); + projectionMap.put(UserIds.IS_PRIMARY, UserIds.IS_PRIMARY); + qb.setProjectionMap(projectionMap); - qb.setProjectionMap(getProjectionMapForKeys()); + qb.setTables(Tables.USER_IDS); + qb.appendWhere(UserIdsColumns.MASTER_KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(1)); break; - case PUBLIC_KEY_RING_KEY_BY_ROW_ID: - case SECRET_KEY_RING_KEY_BY_ROW_ID: - qb.setTables(Tables.KEYS); - qb.appendWhere(KeysColumns.TYPE + " = "); - qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); - qb.appendWhere(" AND " + KeysColumns.KEY_RING_ROW_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + } - qb.appendWhere(" AND " + BaseColumns._ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); + case KEY_RING_PUBLIC: { + HashMap projectionMap = new HashMap(); + projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS_PUBLIC + ".oid AS _id"); + projectionMap.put(KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID); + projectionMap.put(KeyRings.KEY_RING_DATA, KeyRings.KEY_RING_DATA); + qb.setProjectionMap(projectionMap); - qb.setProjectionMap(getProjectionMapForKeys()); + qb.setTables(Tables.KEY_RINGS_PUBLIC); + qb.appendWhere(KeyRingsColumns.MASTER_KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(1)); break; - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID_USER_ID: - qb.setTables(Tables.USER_IDS + " INNER JOIN " + Tables.KEY_RINGS + " ON " + "(" - + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "." - + KeysColumns.KEY_RING_ROW_ID + " )"); - qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(3)); + } - qb.setProjectionMap(getProjectionMapForUserIds()); + case KEY_RING_SECRET: { + HashMap projectionMap = new HashMap(); + projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS_SECRET + ".oid AS _id"); + projectionMap.put(KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID); + projectionMap.put(KeyRings.KEY_RING_DATA, KeyRings.KEY_RING_DATA); + qb.setProjectionMap(projectionMap); - break; - case PUBLIC_KEY_RING_USER_ID: - case SECRET_KEY_RING_USER_ID: - qb.setTables(Tables.USER_IDS); - qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + qb.setTables(Tables.KEY_RINGS_SECRET); + qb.appendWhere(KeyRingsColumns.MASTER_KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(1)); break; - case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: - case SECRET_KEY_RING_USER_ID_BY_ROW_ID: - qb.setTables(Tables.USER_IDS); - qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); - - qb.appendWhere(" AND " + BaseColumns._ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); + } - break; case API_APPS: qb.setTables(Tables.API_APPS); @@ -739,63 +419,36 @@ public class KeychainProvider extends ContentProvider { final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase(); Uri rowUri = null; - long rowId = -1; + Long keyId = null; try { final int match = mUriMatcher.match(uri); switch (match) { - case PUBLIC_KEY_RING: - values.put(KeyRings.TYPE, KeyTypes.PUBLIC); - - rowId = db.insertOrThrow(Tables.KEY_RINGS, null, values); - rowUri = KeyRings.buildPublicKeyRingsUri(Long.toString(rowId)); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); - + case KEY_RING_PUBLIC: + db.insertOrThrow(Tables.KEY_RINGS_PUBLIC, null, values); + keyId = values.getAsLong(KeyRingsColumns.MASTER_KEY_ID); break; - case PUBLIC_KEY_RING_KEY: - values.put(Keys.TYPE, KeyTypes.PUBLIC); - - rowId = db.insertOrThrow(Tables.KEYS, null, values); - // TODO: this is wrong: - rowUri = Keys.buildPublicKeysUri(Long.toString(rowId)); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); + case KEY_RING_SECRET: + db.insertOrThrow(Tables.KEY_RINGS_SECRET, null, values); + keyId = values.getAsLong(KeyRingsColumns.MASTER_KEY_ID); break; - case PUBLIC_KEY_RING_USER_ID: - rowId = db.insertOrThrow(Tables.USER_IDS, null, values); - // TODO: this is wrong: - rowUri = UserIds.buildPublicUserIdsUri(Long.toString(rowId)); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); + case KEY_RING_KEYS: + Log.d(Constants.TAG, "keys"); + db.insertOrThrow(Tables.KEYS, null, values); + keyId = values.getAsLong(KeysColumns.MASTER_KEY_ID); break; - case SECRET_KEY_RING: - values.put(KeyRings.TYPE, KeyTypes.SECRET); - - rowId = db.insertOrThrow(Tables.KEY_RINGS, null, values); - rowUri = KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); + case KEY_RING_USER_IDS: + db.insertOrThrow(Tables.USER_IDS, null, values); + keyId = values.getAsLong(UserIdsColumns.MASTER_KEY_ID); break; - case SECRET_KEY_RING_KEY: - values.put(Keys.TYPE, KeyTypes.SECRET); - rowId = db.insertOrThrow(Tables.KEYS, null, values); - // TODO: this is wrong: - rowUri = Keys.buildSecretKeysUri(Long.toString(rowId)); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); - - break; - case SECRET_KEY_RING_USER_ID: - rowId = db.insertOrThrow(Tables.USER_IDS, null, values); - // TODO: this is wrong: - rowUri = UserIds.buildSecretUserIdsUri(Long.toString(rowId)); - - break; case API_APPS: - rowId = db.insertOrThrow(Tables.API_APPS, null, values); -// rowUri = ApiApps.buildIdUri(Long.toString(rowId)); - + db.insertOrThrow(Tables.API_APPS, null, values); break; + case API_ACCOUNTS: // set foreign key automatically based on given uri // e.g., api_apps/com.example.app/accounts/ @@ -804,20 +457,26 @@ public class KeychainProvider extends ContentProvider { Log.d(Constants.TAG, "provider packageName: " + packageName); - rowId = db.insertOrThrow(Tables.API_ACCOUNTS, null, values); + db.insertOrThrow(Tables.API_ACCOUNTS, null, values); // TODO: this is wrong: // rowUri = ApiAccounts.buildIdUri(Long.toString(rowId)); break; + default: throw new UnsupportedOperationException("Unknown uri: " + uri); } + if(keyId != null) { + uri = KeyRings.buildGenericKeyRingUri(keyId.toString()); + rowUri = uri; + } + // notify of changes in db getContext().getContentResolver().notifyChange(uri, null); } catch (SQLiteConstraintException e) { - Log.e(Constants.TAG, "Constraint exception on insert! Entry already existing?"); + Log.e(Constants.TAG, "Constraint exception on insert! Entry already existing?", e); } return rowUri; @@ -827,7 +486,7 @@ public class KeychainProvider extends ContentProvider { * {@inheritDoc} */ @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { + public int delete(Uri uri, String additionalSelection, String[] selectionArgs) { Log.v(Constants.TAG, "delete(uri=" + uri + ")"); final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase(); @@ -835,43 +494,33 @@ public class KeychainProvider extends ContentProvider { int count; final int match = mUriMatcher.match(uri); - String defaultSelection = null; switch (match) { - case PUBLIC_KEY_RING_BY_ROW_ID: - case SECRET_KEY_RING_BY_ROW_ID: - defaultSelection = BaseColumns._ID + "=" + uri.getLastPathSegment(); - // corresponding keys and userIds are deleted by ON DELETE CASCADE - count = db.delete(Tables.KEY_RINGS, - buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection), - selectionArgs); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); - break; - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: - case SECRET_KEY_RING_BY_MASTER_KEY_ID: - defaultSelection = KeyRings.MASTER_KEY_ID + "=" + uri.getLastPathSegment(); + case KEY_RING_PUBLIC: { + @SuppressWarnings("ConstantConditions") // ensured by uriMatcher above + String selection = KeyRings.MASTER_KEY_ID + " = " + uri.getPathSegments().get(1); + if (!TextUtils.isEmpty(additionalSelection)) { + selection += " AND (" + additionalSelection + ")"; + } // corresponding keys and userIds are deleted by ON DELETE CASCADE - count = db.delete(Tables.KEY_RINGS, - buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection), - selectionArgs); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); + count = db.delete(Tables.KEY_RINGS_PUBLIC, selection, selectionArgs); break; - case PUBLIC_KEY_RING_KEY_BY_ROW_ID: - case SECRET_KEY_RING_KEY_BY_ROW_ID: - count = db.delete(Tables.KEYS, - buildDefaultKeysSelection(uri, getKeyType(match), selection), selectionArgs); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); - break; - case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: - case SECRET_KEY_RING_USER_ID_BY_ROW_ID: - count = db.delete(Tables.KEYS, buildDefaultUserIdsSelection(uri, selection), - selectionArgs); + } + case KEY_RING_SECRET: { + @SuppressWarnings("ConstantConditions") // ensured by uriMatcher above + String selection = KeyRings.MASTER_KEY_ID + " = " + uri.getPathSegments().get(1); + if (!TextUtils.isEmpty(additionalSelection)) { + selection += " AND (" + additionalSelection + ")"; + } + count = db.delete(Tables.KEY_RINGS_SECRET, selection, selectionArgs); break; + } + case API_APPS_BY_PACKAGE_NAME: - count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, selection), + count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, additionalSelection), selectionArgs); break; case API_ACCOUNTS_BY_ACCOUNT_NAME: - count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, selection), + count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, additionalSelection), selectionArgs); break; default: @@ -898,44 +547,6 @@ public class KeychainProvider extends ContentProvider { try { final int match = mUriMatcher.match(uri); switch (match) { - case PUBLIC_KEY_RING_BY_ROW_ID: - case SECRET_KEY_RING_BY_ROW_ID: - defaultSelection = BaseColumns._ID + "=" + uri.getLastPathSegment(); - - count = db.update( - Tables.KEY_RINGS, - values, - buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), - selection), selectionArgs); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); - - break; - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: - case SECRET_KEY_RING_BY_MASTER_KEY_ID: - defaultSelection = KeyRings.MASTER_KEY_ID + "=" + uri.getLastPathSegment(); - - count = db.update( - Tables.KEY_RINGS, - values, - buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), - selection), selectionArgs); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); - - break; - case PUBLIC_KEY_RING_KEY_BY_ROW_ID: - case SECRET_KEY_RING_KEY_BY_ROW_ID: - count = db - .update(Tables.KEYS, values, - buildDefaultKeysSelection(uri, getKeyType(match), selection), - selectionArgs); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); - - break; - case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: - case SECRET_KEY_RING_USER_ID_BY_ROW_ID: - count = db.update(Tables.USER_IDS, values, - buildDefaultUserIdsSelection(uri, selection), selectionArgs); - break; case API_APPS_BY_PACKAGE_NAME: count = db.update(Tables.API_APPS, values, buildDefaultApiAppsSelection(uri, selection), selectionArgs); @@ -958,81 +569,6 @@ public class KeychainProvider extends ContentProvider { return count; } - /** - * Build default selection statement for KeyRings. If no extra selection is specified only build - * where clause with rowId - * - * @param defaultSelection - * @param keyType - * @param selection - * @return - */ - private String buildDefaultKeyRingsSelection(String defaultSelection, Integer keyType, - String selection) { - String andType = ""; - if (keyType != null) { - andType = " AND " + KeyRingsColumns.TYPE + "=" + keyType; - } - - String andSelection = ""; - if (!TextUtils.isEmpty(selection)) { - andSelection = " AND (" + selection + ")"; - } - - return defaultSelection + andType + andSelection; - } - - /** - * Build default selection statement for Keys. If no extra selection is specified only build - * where clause with rowId - * - * @param uri - * @param selection - * @return - */ - private String buildDefaultKeysSelection(Uri uri, Integer keyType, String selection) { - String rowId = uri.getLastPathSegment(); - - String foreignKeyRingRowId = uri.getPathSegments().get(2); - String andForeignKeyRing = " AND " + KeysColumns.KEY_RING_ROW_ID + " = " - + foreignKeyRingRowId; - - String andType = ""; - if (keyType != null) { - andType = " AND " + KeysColumns.TYPE + "=" + keyType; - } - - String andSelection = ""; - if (!TextUtils.isEmpty(selection)) { - andSelection = " AND (" + selection + ")"; - } - - return BaseColumns._ID + "=" + rowId + andForeignKeyRing + andType + andSelection; - } - - /** - * Build default selection statement for UserIds. If no extra selection is specified only build - * where clause with rowId - * - * @param uri - * @param selection - * @return - */ - private String buildDefaultUserIdsSelection(Uri uri, String selection) { - String rowId = uri.getLastPathSegment(); - - String foreignKeyRingRowId = uri.getPathSegments().get(2); - String andForeignKeyRing = " AND " + KeysColumns.KEY_RING_ROW_ID + " = " - + foreignKeyRingRowId; - - String andSelection = ""; - if (!TextUtils.isEmpty(selection)) { - andSelection = " AND (" + selection + ")"; - } - - return BaseColumns._ID + "=" + rowId + andForeignKeyRing + andSelection; - } - /** * Build default selection statement for API apps. If no extra selection is specified only build * where clause with rowId @@ -1066,28 +602,4 @@ public class KeychainProvider extends ContentProvider { + andSelection; } - // @Override - // public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { - // int match = mUriMatcher.match(uri); - // if (match != DATA_STREAM) { - // throw new FileNotFoundException(); - // } - // String fileName = uri.getLastPathSegment(); - // File file = new File(getContext().getFilesDir().getAbsolutePath(), fileName); - // return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); - // } - - /** - * This broadcast is send system wide to inform other application that a keyring was inserted, - * updated, or deleted - */ - private void sendBroadcastDatabaseChange(int keyType, String contentItemType) { - // TODO: Disabled, old API - // Intent intent = new Intent(); - // intent.setAction(ACTION_BROADCAST_DATABASE_CHANGE); - // intent.putExtra(EXTRA_BROADCAST_KEY_TYPE, keyType); - // intent.putExtra(EXTRA_BROADCAST_CONTENT_ITEM_TYPE, contentItemType); - // - // getContext().sendBroadcast(intent, Constants.PERMISSION_ACCESS_API); - } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobDatabase.java index da1bcb2d9..bc7de0b37 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobDatabase.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobDatabase.java @@ -25,7 +25,7 @@ import android.provider.BaseColumns; import org.sufficientlysecure.keychain.provider.KeychainServiceBlobContract.BlobsColumns; public class KeychainServiceBlobDatabase extends SQLiteOpenHelper { - private static final String DATABASE_NAME = "apg_blob.db"; + private static final String DATABASE_NAME = "openkeychain_blob.db"; private static final int DATABASE_VERSION = 2; public static final String TABLE = "data"; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index b971143ae..040923c33 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -75,78 +75,40 @@ public class ProviderHelper { return keyRing; } - /** - * Retrieves the actual PGPPublicKeyRing object from the database blob based on the rowId - */ - public static PGPPublicKeyRing getPGPPublicKeyRingByRowId(Context context, long rowId) { - Uri queryUri = KeyRings.buildPublicKeyRingsUri(Long.toString(rowId)); - return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri); + public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) { + return getPGPPublicKeyRingWithKeyId(context, keyId).getPublicKey(keyId); } - - /** - * Retrieves the actual PGPPublicKeyRing object from the database blob based on the masterKeyId - */ - public static PGPPublicKeyRing getPGPPublicKeyRingByMasterKeyId(Context context, - long masterKeyId) { - Uri queryUri = KeyRings.buildPublicKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId)); - return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri); + public static PGPPublicKeyRing getPGPPublicKeyRingWithKeyId(Context context, long keyId) { + // todo do + return null; } - /** - * Retrieves the actual PGPPublicKeyRing object from the database blob associated with a key - * with this keyId - */ - public static PGPPublicKeyRing getPGPPublicKeyRingByKeyId(Context context, long keyId) { - Uri queryUri = KeyRings.buildPublicKeyRingsByKeyIdUri(Long.toString(keyId)); - return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri); + public static PGPSecretKey getPGPSecretKeyByKeyId(Context context, long keyId) { + return getPGPSecretKeyRingWithKeyId(context, keyId).getSecretKey(keyId); } - - /** - * Retrieves the actual PGPPublicKey object from the database blob associated with a key with - * this keyId - */ - public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) { - PGPPublicKeyRing keyRing = getPGPPublicKeyRingByKeyId(context, keyId); - - return (keyRing == null) ? null : keyRing.getPublicKey(keyId); + public static PGPSecretKeyRing getPGPSecretKeyRingWithKeyId(Context context, long keyId) { + // todo do + return null; } /** - * Retrieves the actual PGPSecretKeyRing object from the database blob based on the rowId + * Retrieves the actual PGPPublicKeyRing object from the database blob based on the masterKeyId */ - public static PGPSecretKeyRing getPGPSecretKeyRingByRowId(Context context, long rowId) { - Uri queryUri = KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)); - return (PGPSecretKeyRing) getPGPKeyRing(context, queryUri); + public static PGPPublicKeyRing getPGPPublicKeyRing(Context context, + long masterKeyId) { + Uri queryUri = KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)); + return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri); } /** * Retrieves the actual PGPSecretKeyRing object from the database blob based on the maserKeyId */ - public static PGPSecretKeyRing getPGPSecretKeyRingByMasterKeyId(Context context, + public static PGPSecretKeyRing getPGPSecretKeyRing(Context context, long masterKeyId) { - Uri queryUri = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId)); - return (PGPSecretKeyRing) getPGPKeyRing(context, queryUri); - } - - /** - * Retrieves the actual PGPSecretKeyRing object from the database blob associated with a key - * with this keyId - */ - public static PGPSecretKeyRing getPGPSecretKeyRingByKeyId(Context context, long keyId) { - Uri queryUri = KeyRings.buildSecretKeyRingsByKeyIdUri(Long.toString(keyId)); + Uri queryUri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId)); return (PGPSecretKeyRing) getPGPKeyRing(context, queryUri); } - /** - * Retrieves the actual PGPSecretKey object from the database blob associated with a key with - * this keyId - */ - public static PGPSecretKey getPGPSecretKeyByKeyId(Context context, long keyId) { - PGPSecretKeyRing keyRing = getPGPSecretKeyRingByKeyId(context, keyId); - - return (keyRing == null) ? null : keyRing.getSecretKey(keyId); - } - /** * Saves PGPPublicKeyRing with its keys and userIds in DB */ @@ -155,21 +117,13 @@ public class ProviderHelper { PGPPublicKey masterKey = keyRing.getPublicKey(); long masterKeyId = masterKey.getKeyID(); - Uri deleteUri = KeyRings.buildPublicKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId)); - - // get current _ID of key - long currentRowId = -1; - Cursor oldQuery = context.getContentResolver() - .query(deleteUri, new String[]{KeyRings._ID}, null, null, null); - if (oldQuery != null && oldQuery.moveToFirst()) { - currentRowId = oldQuery.getLong(0); - } else { - Log.e(Constants.TAG, "Key could not be found! Something wrong is happening!"); - } + // IF there is a secret key, preserve it! + // TODO This even necessary? + // PGPSecretKeyRing secretRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId); // delete old version of this keyRing, which also deletes all keys and userIds on cascade try { - context.getContentResolver().delete(deleteUri, null, null); + context.getContentResolver().delete(KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null); } catch (UnsupportedOperationException e) { Log.e(Constants.TAG, "Key could not be deleted! Maybe we are creating a new one!", e); } @@ -179,29 +133,25 @@ public class ProviderHelper { // NOTE: If we would not use the same _ID again, // getting back to the ViewKeyActivity would result in Nullpointer, // because the currently loaded key would be gone from the database - if (currentRowId != -1) { - values.put(KeyRings._ID, currentRowId); - } values.put(KeyRings.MASTER_KEY_ID, masterKeyId); values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded()); // insert new version of this keyRing - Uri uri = KeyRings.buildPublicKeyRingsUri(); + Uri uri = KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)); Uri insertedUri = context.getContentResolver().insert(uri, values); - long keyRingRowId = Long.valueOf(insertedUri.getLastPathSegment()); // save all keys and userIds included in keyRing object in database ArrayList operations = new ArrayList(); int rank = 0; for (PGPPublicKey key : new IterableIterator(keyRing.getPublicKeys())) { - operations.add(buildPublicKeyOperations(context, keyRingRowId, key, rank)); + operations.add(buildPublicKeyOperations(context, masterKeyId, key, rank)); ++rank; } int userIdRank = 0; for (String userId : new IterableIterator(masterKey.getUserIDs())) { - operations.add(buildPublicUserIdOperations(context, keyRingRowId, userId, userIdRank)); + operations.add(buildUserIdOperations(context, masterKeyId, userId, userIdRank)); ++userIdRank; } @@ -214,7 +164,6 @@ public class ProviderHelper { // operations.add(buildPublicKeyOperations(context, keyRingRowId, key, rank)); } - try { context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY, operations); } catch (RemoteException e) { @@ -222,6 +171,12 @@ public class ProviderHelper { } catch (OperationApplicationException e) { Log.e(Constants.TAG, "applyBatch failed!", e); } + + // Save the saved keyring (if any) + // TODO this even necessary? see above... + // if(secretRing != null) + // saveKeyRing(context, secretRing); + } /** @@ -232,104 +187,46 @@ public class ProviderHelper { PGPSecretKey masterKey = keyRing.getSecretKey(); long masterKeyId = masterKey.getKeyID(); - Uri deleteUri = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId)); - - // get current _ID of key - long currentRowId = -1; - Cursor oldQuery = context.getContentResolver() - .query(deleteUri, new String[]{KeyRings._ID}, null, null, null); - if (oldQuery != null && oldQuery.moveToFirst()) { - currentRowId = oldQuery.getLong(0); - } else { - Log.e(Constants.TAG, "Key could not be found! Something wrong is happening!"); - } + // TODO Make sure there is a public key for this secret key in the db (create one maybe) - // delete old version of this keyRing, which also deletes all keys and userIds on cascade - try { - context.getContentResolver().delete(deleteUri, null, null); - } catch (UnsupportedOperationException e) { - Log.e(Constants.TAG, "Key could not be deleted! Maybe we are creating a new one!", e); + { + ContentValues values = new ContentValues(); + values.put(KeyRings.MASTER_KEY_ID, masterKeyId); + values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded()); + // insert new version of this keyRing + Uri uri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId)); + context.getContentResolver().insert(uri, values); } - ContentValues values = new ContentValues(); - // use exactly the same _ID again to replace key in-place. - // NOTE: If we would not use the same _ID again, - // getting back to the ViewKeyActivity would result in Nullpointer, - // because the currently loaded key would be gone from the database - if (currentRowId != -1) { - values.put(KeyRings._ID, currentRowId); - } - values.put(KeyRings.MASTER_KEY_ID, masterKeyId); - values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded()); - - // insert new version of this keyRing - Uri uri = KeyRings.buildSecretKeyRingsUri(); - Uri insertedUri = context.getContentResolver().insert(uri, values); - long keyRingRowId = Long.valueOf(insertedUri.getLastPathSegment()); - - // save all keys and userIds included in keyRing object in database - ArrayList operations = new ArrayList(); - - int rank = 0; - for (PGPSecretKey key : new IterableIterator(keyRing.getSecretKeys())) { - operations.add(buildSecretKeyOperations(context, keyRingRowId, key, rank)); - ++rank; - } - - int userIdRank = 0; - for (String userId : new IterableIterator(masterKey.getUserIDs())) { - operations.add(buildSecretUserIdOperations(context, keyRingRowId, userId, userIdRank)); - ++userIdRank; - } - - try { - context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY, operations); - } catch (RemoteException e) { - Log.e(Constants.TAG, "applyBatch failed!", e); - } catch (OperationApplicationException e) { - Log.e(Constants.TAG, "applyBatch failed!", e); - } } /** * Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing */ private static ContentProviderOperation buildPublicKeyOperations(Context context, - long keyRingRowId, PGPPublicKey key, int rank) throws IOException { + long masterKeyId, PGPPublicKey key, int rank) throws IOException { + ContentValues values = new ContentValues(); + values.put(Keys.MASTER_KEY_ID, masterKeyId); + values.put(Keys.RANK, rank); + values.put(Keys.KEY_ID, key.getKeyID()); - values.put(Keys.IS_MASTER_KEY, key.isMasterKey()); - values.put(Keys.ALGORITHM, key.getAlgorithm()); values.put(Keys.KEY_SIZE, key.getBitStrength()); - values.put(Keys.CAN_SIGN, PgpKeyHelper.isSigningKey(key)); + values.put(Keys.ALGORITHM, key.getAlgorithm()); + values.put(Keys.FINGERPRINT, key.getFingerprint()); + + values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key))); + values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key))); values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key)); values.put(Keys.IS_REVOKED, key.isRevoked()); + values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000); Date expiryDate = PgpKeyHelper.getExpiryDate(key); if (expiryDate != null) { values.put(Keys.EXPIRY, expiryDate.getTime() / 1000); } - values.put(Keys.KEY_RING_ROW_ID, keyRingRowId); - values.put(Keys.KEY_DATA, key.getEncoded()); - values.put(Keys.RANK, rank); - values.put(Keys.FINGERPRINT, key.getFingerprint()); - - Uri uri = Keys.buildPublicKeysUri(Long.toString(keyRingRowId)); - - return ContentProviderOperation.newInsert(uri).withValues(values).build(); - } - - /** - * Build ContentProviderOperation to add PublicUserIds to database corresponding to a keyRing - */ - private static ContentProviderOperation buildPublicUserIdOperations(Context context, - long keyRingRowId, String userId, int rank) { - ContentValues values = new ContentValues(); - values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId); - values.put(UserIds.USER_ID, userId); - values.put(UserIds.RANK, rank); - Uri uri = UserIds.buildPublicUserIdsUri(Long.toString(keyRingRowId)); + Uri uri = Keys.buildKeysUri(Long.toString(masterKeyId)); return ContentProviderOperation.newInsert(uri).withValues(values).build(); } @@ -338,50 +235,21 @@ public class ProviderHelper { * Build ContentProviderOperation to add PGPSecretKey to database corresponding to a keyRing */ private static ContentProviderOperation buildSecretKeyOperations(Context context, - long keyRingRowId, PGPSecretKey key, int rank) throws IOException { - ContentValues values = new ContentValues(); - - boolean hasPrivate = true; - if (key.isMasterKey()) { - if (key.isPrivateKeyEmpty()) { - hasPrivate = false; - } - } - - values.put(Keys.KEY_ID, key.getKeyID()); - values.put(Keys.IS_MASTER_KEY, key.isMasterKey()); - values.put(Keys.ALGORITHM, key.getPublicKey().getAlgorithm()); - values.put(Keys.KEY_SIZE, key.getPublicKey().getBitStrength()); - values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key) && hasPrivate)); - values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key) && hasPrivate)); - values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key)); - values.put(Keys.IS_REVOKED, key.getPublicKey().isRevoked()); - values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000); - Date expiryDate = PgpKeyHelper.getExpiryDate(key); - if (expiryDate != null) { - values.put(Keys.EXPIRY, expiryDate.getTime() / 1000); - } - values.put(Keys.KEY_RING_ROW_ID, keyRingRowId); - values.put(Keys.KEY_DATA, key.getEncoded()); - values.put(Keys.RANK, rank); - values.put(Keys.FINGERPRINT, key.getPublicKey().getFingerprint()); - - Uri uri = Keys.buildSecretKeysUri(Long.toString(keyRingRowId)); - - return ContentProviderOperation.newInsert(uri).withValues(values).build(); + long masterKeyId, PGPSecretKey key, int rank) throws IOException { + return buildPublicKeyOperations(context, masterKeyId, key.getPublicKey(), rank); } /** - * Build ContentProviderOperation to add SecretUserIds to database corresponding to a keyRing + * Build ContentProviderOperation to add PublicUserIds to database corresponding to a keyRing */ - private static ContentProviderOperation buildSecretUserIdOperations(Context context, - long keyRingRowId, String userId, int rank) { + private static ContentProviderOperation buildUserIdOperations(Context context, + long masterKeyId, String userId, int rank) { ContentValues values = new ContentValues(); - values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId); + values.put(UserIds.MASTER_KEY_ID, masterKeyId); values.put(UserIds.USER_ID, userId); values.put(UserIds.RANK, rank); - Uri uri = UserIds.buildSecretUserIdsUri(Long.toString(keyRingRowId)); + Uri uri = UserIds.buildUserIdsUri(Long.toString(masterKeyId)); return ContentProviderOperation.newInsert(uri).withValues(values).build(); } @@ -410,141 +278,54 @@ public class ProviderHelper { return masterKeyIds; } - /** - * Private helper method - */ - private static ArrayList getKeyRingsRowIds(Context context, Uri queryUri) { - Cursor cursor = context.getContentResolver().query(queryUri, - new String[]{KeyRings._ID}, null, null, null); - - ArrayList rowIds = new ArrayList(); - if (cursor != null) { - int idCol = cursor.getColumnIndex(KeyRings._ID); - if (cursor.moveToFirst()) { - do { - rowIds.add(cursor.getLong(idCol)); - } while (cursor.moveToNext()); - } - } - - if (cursor != null) { - cursor.close(); - } - - return rowIds; - } - - /** - * Retrieves ids of all SecretKeyRings - */ - public static ArrayList getSecretKeyRingsMasterKeyIds(Context context) { - Uri queryUri = KeyRings.buildSecretKeyRingsUri(); - return getKeyRingsMasterKeyIds(context, queryUri); - } - - /** - * Retrieves ids of all PublicKeyRings - */ - public static ArrayList getPublicKeyRingsMasterKeyIds(Context context) { - Uri queryUri = KeyRings.buildPublicKeyRingsUri(); - return getKeyRingsMasterKeyIds(context, queryUri); - } - - /** - * Retrieves ids of all SecretKeyRings - */ - public static ArrayList getSecretKeyRingsRowIds(Context context) { - Uri queryUri = KeyRings.buildSecretKeyRingsUri(); - return getKeyRingsRowIds(context, queryUri); - } - - /** - * Retrieves ids of all PublicKeyRings - */ - public static ArrayList getPublicKeyRingsRowIds(Context context) { - Uri queryUri = KeyRings.buildPublicKeyRingsUri(); - return getKeyRingsRowIds(context, queryUri); - } - - public static void deletePublicKeyRing(Context context, long rowId) { + public static void deletePublicKeyRing(Context context, long masterKeyId) { ContentResolver cr = context.getContentResolver(); - cr.delete(KeyRings.buildPublicKeyRingsUri(Long.toString(rowId)), null, null); + cr.delete(KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null); } - public static void deleteSecretKeyRing(Context context, long rowId) { + public static void deleteSecretKeyRing(Context context, long masterKeyId) { ContentResolver cr = context.getContentResolver(); - cr.delete(KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)), null, null); - } - - public static void deleteUnifiedKeyRing(Context context, String masterKeyId, boolean isSecretKey) { - ContentResolver cr = context.getContentResolver(); - cr.delete(KeyRings.buildPublicKeyRingsByMasterKeyIdUri(masterKeyId), null, null); - if (isSecretKey) { - cr.delete(KeyRings.buildSecretKeyRingsByMasterKeyIdUri(masterKeyId), null, null); - } - + cr.delete(KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId)), null, null); } - /** - * Get master key id of keyring by its row id - */ - public static long getPublicMasterKeyId(Context context, long keyRingRowId) { - Uri queryUri = KeyRings.buildPublicKeyRingsUri(String.valueOf(keyRingRowId)); - return getMasterKeyId(context, queryUri); - } - - /** - * Get empty status of master key of keyring by its row id - */ - public static boolean getSecretMasterKeyCanCertify(Context context, long keyRingRowId) { - Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId)); - return getMasterKeyCanCertify(context, queryUri); - } + public static boolean getMasterKeyCanCertify(Context context, Uri queryUri) { + // TODO redo - /** - * Private helper method to get master key private empty status of keyring by its row id - */ + return false; - public static boolean getMasterKeyCanCertify(Context context, Uri queryUri) { - String[] projection = new String[]{ - KeyRings.MASTER_KEY_ID, - "(SELECT COUNT(sign_keys." + Keys._ID + ") FROM " + Tables.KEYS - + " AS sign_keys WHERE sign_keys." + Keys.KEY_RING_ROW_ID + " = " - + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID - + " AND sign_keys." + Keys.CAN_CERTIFY + " = '1' AND " + Keys.IS_MASTER_KEY - + " = 1) AS sign",}; + /* + String[] projection = new String[]{ + KeyRings.MASTER_KEY_ID, + "(SELECT COUNT(sign_keys." + Keys._ID + ") FROM " + Tables.KEYS + + " AS sign_keys WHERE sign_keys." + Keys.KEY_RING_ROW_ID + " = " + + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID + + " AND sign_keys." + Keys.CAN_CERTIFY + " = '1' AND " + Keys.IS_MASTER_KEY + + " = 1) AS sign",}; - ContentResolver cr = context.getContentResolver(); - Cursor cursor = cr.query(queryUri, projection, null, null, null); + ContentResolver cr = context.getContentResolver(); + Cursor cursor = cr.query(queryUri, projection, null, null, null); - long masterKeyId = -1; - if (cursor != null && cursor.moveToFirst()) { - int masterKeyIdCol = cursor.getColumnIndex("sign"); + long masterKeyId = -1; + if (cursor != null && cursor.moveToFirst()) { + int masterKeyIdCol = cursor.getColumnIndex("sign"); - masterKeyId = cursor.getLong(masterKeyIdCol); - } + masterKeyId = cursor.getLong(masterKeyIdCol); + } - if (cursor != null) { - cursor.close(); - } + if (cursor != null) { + cursor.close(); + } - return (masterKeyId > 0); + return (masterKeyId > 0); + */ } public static boolean hasSecretKeyByMasterKeyId(Context context, long masterKeyId) { - Uri queryUri = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId)); + Uri queryUri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId)); // see if we can get our master key id back from the uri return getMasterKeyId(context, queryUri) == masterKeyId; } - /** - * Get master key id of keyring by its row id - */ - public static long getSecretMasterKeyId(Context context, long keyRingRowId) { - Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId)); - return getMasterKeyId(context, queryUri); - } - /** * Get master key id of key */ @@ -629,10 +410,10 @@ public class ProviderHelper { } } - PGPPublicKey key = ProviderHelper.getPGPPublicKeyByKeyId(context, masterKeyId); + PGPPublicKey key = ProviderHelper.getPGPPublicKeyRing(context, masterKeyId).getPublicKey(); // if it is no public key get it from your own keys... if (key == null) { - PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, masterKeyId); + PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId).getSecretKey(); if (secretKey == null) { Log.e(Constants.TAG, "Key could not be found!"); return null; @@ -646,26 +427,6 @@ public class ProviderHelper { return fingerprint; } - public static String getUserId(Context context, Uri queryUri) { - String[] projection = new String[]{UserIds.USER_ID}; - Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null); - - String userId = null; - try { - if (cursor != null && cursor.moveToFirst()) { - int col = cursor.getColumnIndexOrThrow(UserIds.USER_ID); - - userId = cursor.getString(col); - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - return userId; - } - public static ArrayList getKeyRingsAsArmoredString(Context context, Uri uri, long[] masterKeyIds) { ArrayList output = new ArrayList(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 1cd5862e7..614fc2c00 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -64,7 +64,7 @@ public class OpenPgpService extends RemoteService { ArrayList dublicateUserIds = new ArrayList(); for (String email : encryptionUserIds) { - Uri uri = KeychainContract.KeyRings.buildPublicKeyRingsByEmailsUri(email); + Uri uri = KeychainContract.KeyRings.buildUnifiedKeyRingsByEmailUri(email); Cursor cur = getContentResolver().query(uri, null, null, null, null); if (cur.moveToFirst()) { long id = cur.getLong(cur.getColumnIndex(KeychainContract.KeyRings.MASTER_KEY_ID)); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index f82e5e619..6997a8f3e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -478,8 +478,7 @@ public class KeychainIntentService extends IntentService /* Operation */ if (!canSign) { PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 50, 100)); - PGPSecretKeyRing keyRing = ProviderHelper - .getPGPSecretKeyRingByKeyId(this, masterKeyId); + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(this, masterKeyId); keyRing = keyOperations.changeSecretKeyPassphrase(keyRing, oldPassPhrase, newPassPhrase); setProgress(R.string.progress_saving_key_ring, 50, 100); @@ -487,8 +486,8 @@ public class KeychainIntentService extends IntentService setProgress(R.string.progress_done, 100, 100); } else { PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 90, 100)); - PGPSecretKeyRing privkey = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, masterKeyId); - PGPPublicKeyRing pubkey = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, masterKeyId); + PGPSecretKeyRing privkey = ProviderHelper.getPGPSecretKeyRing(this, masterKeyId); + PGPPublicKeyRing pubkey = ProviderHelper.getPGPPublicKeyRing(this, masterKeyId); PgpKeyOperation.Pair pair = keyOperations.buildSecretKey(privkey, pubkey, saveParams); setProgress(R.string.progress_saving_key_ring, 90, 100); @@ -639,8 +638,9 @@ public class KeychainIntentService extends IntentService ArrayList publicMasterKeyIds = new ArrayList(); ArrayList secretMasterKeyIds = new ArrayList(); - ArrayList allPublicMasterKeyIds = ProviderHelper.getPublicKeyRingsMasterKeyIds(this); - ArrayList allSecretMasterKeyIds = ProviderHelper.getSecretKeyRingsMasterKeyIds(this); + // TODO redo + ArrayList allPublicMasterKeyIds = null; // ProviderHelper.getPublicKeyRingsMasterKeyIds(this); + ArrayList allSecretMasterKeyIds = null; // ProviderHelper.getSecretKeyRingsMasterKeyIds(this); if (exportAll) { // get all public key ring MasterKey ids @@ -790,8 +790,7 @@ public class KeychainIntentService extends IntentService } PgpKeyOperation keyOperation = new PgpKeyOperation(new ProgressScaler(this, 0, 100, 100)); - PGPPublicKeyRing publicRing = ProviderHelper - .getPGPPublicKeyRingByKeyId(this, pubKeyId); + PGPPublicKeyRing publicRing = ProviderHelper.getPGPPublicKeyRing(this, pubKeyId); PGPPublicKey publicKey = publicRing.getPublicKey(pubKeyId); PGPSecretKey certificationKey = PgpKeyHelper.getCertificationKey(this, masterKeyId); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index 5825db01b..f2ab049c3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -161,7 +161,7 @@ public class PassphraseCacheService extends Service { // try to get master key id which is used as an identifier for cached passphrases long masterKeyId = keyId; if (masterKeyId != Id.key.symmetric) { - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(this, keyId); + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(this, keyId); if (keyRing == null) { return null; } @@ -202,8 +202,7 @@ public class PassphraseCacheService extends Service { public static boolean hasPassphrase(Context context, long secretKeyId) { // check if the key has no passphrase try { - PGPSecretKeyRing secRing = ProviderHelper - .getPGPSecretKeyRingByKeyId(context, secretKeyId); + PGPSecretKeyRing secRing = ProviderHelper.getPGPSecretKeyRing(context, secretKeyId); PGPSecretKey secretKey = null; boolean foundValidKey = false; for (Iterator keys = secRing.getSecretKeys(); keys.hasNext(); ) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index 5dc06c16d..fd6f2186c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -139,8 +139,6 @@ public class CertifyKeyActivity extends ActionBarActivity implements } Log.e(Constants.TAG, "uri: " + mDataUri); - PGPPublicKeyRing signKey = (PGPPublicKeyRing) ProviderHelper.getPGPKeyRing(this, mDataUri); - mUserIds = (ListView) findViewById(R.id.user_ids); mUserIdsAdapter = new ViewKeyUserIdsAdapter(this, null, 0, true); @@ -149,20 +147,12 @@ public class CertifyKeyActivity extends ActionBarActivity implements getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this); getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this); - if (signKey != null) { - mPubKeyId = PgpKeyHelper.getMasterKey(signKey).getKeyID(); - } - if (mPubKeyId == 0) { - Log.e(Constants.TAG, "this shouldn't happen. KeyId == 0!"); - finish(); - return; - } } static final String[] KEYRING_PROJECTION = new String[] { KeychainContract.KeyRings._ID, - KeychainContract.KeyRings.MASTER_KEY_ID, + KeychainContract.Keys.MASTER_KEY_ID, KeychainContract.Keys.FINGERPRINT, KeychainContract.UserIds.USER_ID }; @@ -182,11 +172,13 @@ public class CertifyKeyActivity extends ActionBarActivity implements @Override public Loader onCreateLoader(int id, Bundle args) { switch(id) { - case LOADER_ID_KEYRING: - return new CursorLoader(this, mDataUri, KEYRING_PROJECTION, null, null, null); + case LOADER_ID_KEYRING: { + Uri uri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri); + return new CursorLoader(this, uri, KEYRING_PROJECTION, null, null, null); + } case LOADER_ID_USER_IDS: { - Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri); - return new CursorLoader(this, baseUri, USER_IDS_PROJECTION, null, null, USER_IDS_SORT_ORDER); + Uri uri = KeychainContract.UserIds.buildUserIdsUri(mDataUri); + return new CursorLoader(this, uri, USER_IDS_PROJECTION, null, null, USER_IDS_SORT_ORDER); } } return null; @@ -199,19 +191,14 @@ public class CertifyKeyActivity extends ActionBarActivity implements // the first key here is our master key if (data.moveToFirst()) { // TODO: put findViewById in onCreate! - - long keyId = data.getLong(INDEX_MASTER_KEY_ID); - String keyIdStr = PgpKeyHelper.convertKeyIdToHexShort(keyId); + mPubKeyId = data.getLong(INDEX_MASTER_KEY_ID); + String keyIdStr = PgpKeyHelper.convertKeyIdToHexShort(mPubKeyId); ((TextView) findViewById(R.id.key_id)).setText(keyIdStr); String mainUserId = data.getString(INDEX_USER_ID); ((TextView) findViewById(R.id.main_user_id)).setText(mainUserId); byte[] fingerprintBlob = data.getBlob(INDEX_FINGERPRINT); - if (fingerprintBlob == null) { - // FALLBACK for old database entries - fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri); - } String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); ((TextView) findViewById(R.id.fingerprint)).setText(PgpKeyHelper.colorizeFingerprint(fingerprint)); } @@ -261,7 +248,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements * handles the UI bits of the signing process on the UI thread */ private void initiateSigning() { - PGPPublicKeyRing pubring = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, mPubKeyId); + PGPPublicKeyRing pubring = ProviderHelper.getPGPPublicKeyRing(this, mPubKeyId); if (pubring != null) { // if we have already signed this key, dont bother doing it again boolean alreadySigned = false; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 9df84065f..0d0b7222e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -356,7 +356,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener return true; case R.id.menu_key_edit_delete: long rowId= ProviderHelper.getRowId(this,mDataUri); - Uri convertUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)); + Uri convertUri = KeychainContract.KeyRings.buildSecretKeyRingUri(Long.toString(rowId)); // Message is received after key is deleted Handler returnHandler = new Handler() { @Override @@ -380,7 +380,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener private void finallyEdit(final long masterKeyId) { if (masterKeyId != 0) { PGPSecretKey masterKey = null; - mKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, masterKeyId); + mKeyRing = ProviderHelper.getPGPSecretKeyRing(this, masterKeyId); if (mKeyRing != null) { masterKey = PgpKeyHelper.getMasterKey(mKeyRing); for (PGPSecretKey key : new IterableIterator(mKeyRing.getSecretKeys())) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index 5b7f9e4cc..10508317d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -141,7 +141,7 @@ public class EncryptAsymmetricFragment extends Fragment { private void preselectKeys(long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds) { if (preselectedSignatureKeyId != 0) { // TODO: don't use bouncy castle objects! - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(getActivity(), + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(getActivity(), preselectedSignatureKeyId); PGPSecretKey masterKey; if (keyRing != null) { @@ -160,7 +160,7 @@ public class EncryptAsymmetricFragment extends Fragment { for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) { // TODO: don't use bouncy castle objects! - PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(getActivity(), + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(getActivity(), preselectedEncryptionKeyIds[i]); PGPPublicKey masterKey; if (keyRing == null) { @@ -203,7 +203,7 @@ public class EncryptAsymmetricFragment extends Fragment { String uid = getResources().getString(R.string.user_id_no_name); String uidExtra = ""; // TODO: don't use bouncy castle objects! - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(getActivity(), + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(getActivity(), mSecretKeyId); if (keyRing != null) { PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 957c822d2..573ddd1a7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -186,6 +186,7 @@ public class KeyListFragment extends Fragment case R.id.menu_key_list_multi_export: { ids = mStickyList.getWrappedList().getCheckedItemIds(); long[] masterKeyIds = new long[2*ids.length]; + /* TODO! redo ArrayList allPubRowIds = ProviderHelper.getPublicKeyRingsRowIds(getActivity()); for (int i = 0; i < ids.length; i++) { @@ -194,7 +195,7 @@ public class KeyListFragment extends Fragment } else { masterKeyIds[i] = ProviderHelper.getSecretMasterKeyId(getActivity(), ids[i]); } - } + }*/ ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity()); mExportHelper .showExportKeysDialog(masterKeyIds, Id.type.public_key, @@ -254,22 +255,22 @@ public class KeyListFragment extends Fragment // These are the rows that we will retrieve. static final String[] PROJECTION = new String[]{ KeychainContract.KeyRings._ID, - KeychainContract.KeyRings.TYPE, - KeychainContract.KeyRings.MASTER_KEY_ID, + KeychainContract.Keys.MASTER_KEY_ID, KeychainContract.UserIds.USER_ID, - KeychainContract.Keys.IS_REVOKED + KeychainContract.Keys.IS_REVOKED, + KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID }; - static final int INDEX_TYPE = 1; - static final int INDEX_MASTER_KEY_ID = 2; - static final int INDEX_USER_ID = 3; - static final int INDEX_IS_REVOKED = 4; + static final int INDEX_MASTER_KEY_ID = 1; + static final int INDEX_USER_ID = 2; + static final int INDEX_IS_REVOKED = 3; + static final int INDEX_HAS_SECRET = 4; static final String SORT_ORDER = // show secret before public key - KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings.TYPE + " DESC, " + KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID + " IS NULL ASC, " + // sort by user id otherwise - + UserIds.USER_ID + " ASC"; + UserIds.USER_ID + " ASC"; @Override public Loader onCreateLoader(int id, Bundle args) { @@ -326,7 +327,7 @@ public class KeyListFragment extends Fragment } viewIntent.setData( KeychainContract - .KeyRings.buildPublicKeyRingsByMasterKeyIdUri( + .KeyRings.buildPublicKeyRingUri( Long.toString(mAdapter.getMasterKeyId(position)))); startActivity(viewIntent); } @@ -503,7 +504,7 @@ public class KeyListFragment extends Fragment Button button = (Button) view.findViewById(R.id.edit); TextView revoked = (TextView) view.findViewById(R.id.revoked); - if (cursor.getInt(KeyListFragment.INDEX_TYPE) == KeyTypes.SECRET) { + if (!cursor.isNull(KeyListFragment.INDEX_HAS_SECRET)) { // this is a secret key - show the edit button statusDivider.setVisibility(View.VISIBLE); statusLayout.setVisibility(View.VISIBLE); @@ -516,7 +517,7 @@ public class KeyListFragment extends Fragment Intent editIntent = new Intent(getActivity(), EditKeyActivity.class); editIntent.setData( KeychainContract.KeyRings - .buildSecretKeyRingsByMasterKeyIdUri(Long.toString(id))); + .buildSecretKeyRingUri(Long.toString(id))); editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY); startActivityForResult(editIntent, 0); } @@ -577,7 +578,7 @@ public class KeyListFragment extends Fragment throw new IllegalStateException("couldn't move cursor to position " + position); } - if (mCursor.getInt(KeyListFragment.INDEX_TYPE) == KeyTypes.SECRET) { + if (!mCursor.isNull(KeyListFragment.INDEX_HAS_SECRET)) { { // set contact count int num = mCursor.getCount(); String contactsTotal = getResources().getQuantityString(R.plurals.n_contacts, num, num); @@ -617,7 +618,7 @@ public class KeyListFragment extends Fragment } // early breakout: all secret keys are assigned id 0 - if (mCursor.getInt(KeyListFragment.INDEX_TYPE) == KeyTypes.SECRET) { + if (!mCursor.isNull(KeyListFragment.INDEX_HAS_SECRET)) { return 1L; } // otherwise, return the first character of the name as ID diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java index 6ab9f1c6e..fcce39ee9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java @@ -248,9 +248,7 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T @Override public Loader onCreateLoader(int id, Bundle args) { - // This is called when a new Loader needs to be created. This - // sample only has one Loader, so we don't care about the ID. - Uri baseUri = KeyRings.buildPublicKeyRingsUri(); + Uri baseUri = KeyRings.buildUnifiedKeyRingsUri(); // These are the rows that we will retrieve. long now = new Date().getTime() / 1000; @@ -258,24 +256,24 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T KeyRings._ID, KeyRings.MASTER_KEY_ID, UserIds.USER_ID, - "(SELECT COUNT(available_keys." + Keys._ID + ") FROM " + Tables.KEYS - + " AS available_keys WHERE available_keys." + Keys.KEY_RING_ROW_ID + " = " - + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID - + " AND available_keys." + Keys.IS_REVOKED + " = '0' AND available_keys." - + Keys.CAN_ENCRYPT + " = '1') AS " - + SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE, - "(SELECT COUNT(valid_keys." + Keys._ID + ") FROM " + Tables.KEYS - + " AS valid_keys WHERE valid_keys." + Keys.KEY_RING_ROW_ID + " = " - + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID - + " AND valid_keys." + Keys.IS_REVOKED + " = '0' AND valid_keys." - + Keys.CAN_ENCRYPT + " = '1' AND valid_keys." + Keys.CREATION + " <= '" - + now + "' AND " + "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys." - + Keys.EXPIRY + " >= '" + now + "')) AS " - + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, }; + "(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k" + +" WHERE k." + Keys.MASTER_KEY_ID + " = " + + KeychainDatabase.Tables.KEYS + "." + Keys.MASTER_KEY_ID + + " AND k." + Keys.IS_REVOKED + " = '0'" + + " AND k." + Keys.CAN_ENCRYPT + " = '1'" + + ") AS " + SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE, + "(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k" + + " WHERE k." + Keys.MASTER_KEY_ID + " = " + + KeychainDatabase.Tables.KEYS + "." + Keys.MASTER_KEY_ID + + " AND k." + Keys.IS_REVOKED + " = '0'" + + " AND k." + Keys.CAN_ENCRYPT + " = '1'" + + " AND k." + Keys.CREATION + " <= '" + now + "'" + + " AND ( k." + Keys.EXPIRY + " IS NULL OR k." + Keys.EXPIRY + " >= '" + now + "' )" + + ") AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, }; String inMasterKeyList = null; if (mSelectedMasterKeyIds != null && mSelectedMasterKeyIds.length > 0) { - inMasterKeyList = KeyRings.MASTER_KEY_ID + " IN ("; + inMasterKeyList = Tables.KEYS + "." + KeyRings.MASTER_KEY_ID + " IN ("; for (int i = 0; i < mSelectedMasterKeyIds.length; ++i) { if (i != 0) { inMasterKeyList += ", "; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java index 2efa7d33a..9987facbc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java @@ -85,7 +85,7 @@ public class SelectSecretKeyFragment extends ListFragment implements @Override public void onItemClick(AdapterView adapterView, View view, int position, long id) { long masterKeyId = mAdapter.getMasterKeyId(position); - Uri result = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(masterKeyId)); + Uri result = KeyRings.buildGenericKeyRingUri(String.valueOf(masterKeyId)); // return data to activity, which results in finishing it mActivity.afterListSelection(result); @@ -112,12 +112,7 @@ public class SelectSecretKeyFragment extends ListFragment implements public Loader onCreateLoader(int id, Bundle args) { // This is called when a new Loader needs to be created. This // sample only has one Loader, so we don't care about the ID. - Uri baseUri = KeyRings.buildSecretKeyRingsUri(); - - String capFilter = null; - if (mFilterCertify) { - capFilter = "(cert > 0)"; - } + Uri baseUri = KeyRings.buildUnifiedKeyRingsUri(); // These are the rows that we will retrieve. long now = new Date().getTime() / 1000; @@ -125,29 +120,36 @@ public class SelectSecretKeyFragment extends ListFragment implements KeyRings._ID, KeyRings.MASTER_KEY_ID, UserIds.USER_ID, - "(SELECT COUNT(cert_keys." + Keys._ID + ") FROM " + Tables.KEYS - + " AS cert_keys WHERE cert_keys." + Keys.KEY_RING_ROW_ID + " = " - + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID + " AND cert_keys." - + Keys.CAN_CERTIFY + " = '1') AS cert", - "(SELECT COUNT(available_keys." + Keys._ID + ") FROM " + Tables.KEYS - + " AS available_keys WHERE available_keys." + Keys.KEY_RING_ROW_ID + " = " - + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID - + " AND available_keys." + Keys.IS_REVOKED + " = '0' AND available_keys." - + Keys.CAN_SIGN + " = '1') AS " - + SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE, - "(SELECT COUNT(valid_keys." + Keys._ID + ") FROM " + Tables.KEYS - + " AS valid_keys WHERE valid_keys." + Keys.KEY_RING_ROW_ID + " = " - + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID + " AND valid_keys." - + Keys.IS_REVOKED + " = '0' AND valid_keys." + Keys.CAN_SIGN - + " = '1' AND valid_keys." + Keys.CREATION + " <= '" + now + "' AND " - + "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys." + Keys.EXPIRY - + " >= '" + now + "')) AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID,}; + "(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k" + + " WHERE k." + Keys.MASTER_KEY_ID + " = " + + KeychainDatabase.Tables.KEYS + "." + KeyRings.MASTER_KEY_ID + + " AND k." + Keys.CAN_CERTIFY + " = '1'" + + ") AS cert", + "(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k" + +" WHERE k." + Keys.MASTER_KEY_ID + " = " + + KeychainDatabase.Tables.KEYS + "." + Keys.MASTER_KEY_ID + + " AND k." + Keys.IS_REVOKED + " = '0'" + + " AND k." + Keys.CAN_SIGN + " = '1'" + + ") AS " + SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE, + "(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k" + + " WHERE k." + Keys.MASTER_KEY_ID + " = " + + KeychainDatabase.Tables.KEYS + "." + Keys.MASTER_KEY_ID + + " AND k." + Keys.IS_REVOKED + " = '0'" + + " AND k." + Keys.CAN_SIGN + " = '1'" + + " AND k." + Keys.CREATION + " <= '" + now + "'" + + " AND ( k." + Keys.EXPIRY + " IS NULL OR k." + Keys.EXPIRY + " >= '" + now + "' )" + + ") AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, }; String orderBy = UserIds.USER_ID + " ASC"; + String where = Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + " IS NOT NULL"; + if (mFilterCertify) { + where += " AND (cert > 0)"; + } + // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. - return new CursorLoader(getActivity(), baseUri, projection, capFilter, null, orderBy); + return new CursorLoader(getActivity(), baseUri, projection, where, null, orderBy); } @Override diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java index cbc0f4c5c..95eb4df94 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java @@ -57,10 +57,12 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan //The Projection we will retrieve, Master Key ID is for convenience sake, //to avoid having to pass the Key Around - final String[] PROJECTION = new String[]{KeychainContract.UserIds.USER_ID - , KeychainContract.KeyRings.MASTER_KEY_ID}; - final int INDEX_USER_ID = 0; - final int INDEX_MASTER_KEY_ID = 1; + final String[] PROJECTION = new String[] { + KeychainContract.Keys.MASTER_KEY_ID, + KeychainContract.UserIds.USER_ID + }; + final int INDEX_MASTER_KEY_ID = 0; + final int INDEX_USER_ID = 1; public interface SelectSecretKeyCallback { void onKeySelected(long secretKeyId); @@ -126,7 +128,7 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan //For AppSettingsFragment public void selectKey(long masterKeyId) { - Uri buildUri = KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(masterKeyId)); + Uri buildUri = KeychainContract.KeyRings.buildGenericKeyRingUri(String.valueOf(masterKeyId)); mReceivedUri = buildUri; getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this); } @@ -139,8 +141,9 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan @Override public Loader onCreateLoader(int id, Bundle args) { + Uri uri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mReceivedUri); //We don't care about the Loader id - return new CursorLoader(getActivity(), mReceivedUri, PROJECTION, null, null, null); + return new CursorLoader(getActivity(), uri, PROJECTION, null, null, null); } @Override diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 3e7e6d7ce..c212bea1f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -83,13 +83,7 @@ public class ViewKeyActivity extends ActionBarActivity { selectedTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB); } - { - // normalize mDataUri to a "by row id" query, to ensure it works with any - // given valid /public/ query - long rowId = ProviderHelper.getRowId(this, getIntent().getData()); - // TODO: handle (rowId == 0) with something else than a crash - mDataUri = KeychainContract.KeyRings.buildPublicKeyRingsUri(Long.toString(rowId)); - } + mDataUri = getIntent().getData(); Bundle mainBundle = new Bundle(); mainBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, mDataUri); @@ -124,8 +118,7 @@ public class ViewKeyActivity extends ActionBarActivity { uploadToKeyserver(mDataUri); return true; case R.id.menu_key_view_export_file: - long masterKeyId = - ProviderHelper.getPublicMasterKeyId(this, Long.valueOf(mDataUri.getLastPathSegment())); + long masterKeyId = Long.valueOf(mDataUri.getLastPathSegment()); long[] ids = new long[]{masterKeyId}; mExportHelper.showExportKeysDialog(ids, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB, null); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index 691be5fa9..397cfafa7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -69,7 +69,6 @@ public class ViewKeyMainFragment extends Fragment implements private ListView mUserIds; private ListView mKeys; - private static final int LOADER_ID_KEYRING = 0; private static final int LOADER_ID_USER_IDS = 1; private static final int LOADER_ID_KEYS = 2; @@ -144,7 +143,7 @@ public class ViewKeyMainFragment extends Fragment implements Intent editIntent = new Intent(getActivity(), EditKeyActivity.class); editIntent.setData( KeychainContract - .KeyRings.buildSecretKeyRingsByMasterKeyIdUri( + .KeyRings.buildSecretKeyRingUri( Long.toString(masterKeyId))); editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY); startActivityForResult(editIntent, 0); @@ -163,7 +162,7 @@ public class ViewKeyMainFragment extends Fragment implements // TODO see todo note above, doing this here for now mActionCertify.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { - certifyKey(KeychainContract.KeyRings.buildPublicKeyRingsByMasterKeyIdUri( + certifyKey(KeychainContract.KeyRings.buildGenericKeyRingUri( Long.toString(masterKeyId) )); } @@ -187,39 +186,31 @@ public class ViewKeyMainFragment extends Fragment implements // Prepare the loaders. Either re-connect with an existing ones, // or start new ones. - getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this); getActivity().getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this); getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this); } - static final String[] KEYRING_PROJECTION = - new String[]{KeychainContract.KeyRings._ID, KeychainContract.KeyRings.MASTER_KEY_ID, - KeychainContract.UserIds.USER_ID}; - static final int KEYRING_INDEX_ID = 0; - static final int KEYRING_INDEX_MASTER_KEY_ID = 1; - static final int KEYRING_INDEX_USER_ID = 2; - static final String[] USER_IDS_PROJECTION = new String[]{ KeychainContract.UserIds._ID, KeychainContract.UserIds.USER_ID, KeychainContract.UserIds.RANK, }; + static final int INDEX_UID_UID = 1; static final String USER_IDS_SORT_ORDER = KeychainContract.UserIds.RANK + " COLLATE LOCALIZED ASC"; static final String[] KEYS_PROJECTION = new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID, - KeychainContract.Keys.IS_MASTER_KEY, KeychainContract.Keys.ALGORITHM, + KeychainContract.Keys.ALGORITHM, KeychainContract.Keys.RANK, KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY, KeychainContract.Keys.CAN_SIGN, KeychainContract.Keys.CAN_ENCRYPT, KeychainContract.Keys.IS_REVOKED, KeychainContract.Keys.CREATION, KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT}; static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC"; - static final int KEYS_INDEX_ID = 0; static final int KEYS_INDEX_KEY_ID = 1; - static final int KEYS_INDEX_IS_MASTER_KEY = 2; - static final int KEYS_INDEX_ALGORITHM = 3; + static final int KEYS_INDEX_ALGORITHM = 2; + static final int KEYS_INDEX_RANK = 3; static final int KEYS_INDEX_KEY_SIZE = 4; static final int KEYS_INDEX_CAN_CERTIFY = 5; static final int KEYS_INDEX_CAN_SIGN = 6; @@ -231,13 +222,6 @@ public class ViewKeyMainFragment extends Fragment implements public Loader onCreateLoader(int id, Bundle args) { switch (id) { - case LOADER_ID_KEYRING: { - Uri baseUri = mDataUri; - - // Now create and return a CursorLoader that will take care of - // creating a Cursor for the data being displayed. - return new CursorLoader(getActivity(), baseUri, KEYRING_PROJECTION, null, null, null); - } case LOADER_ID_USER_IDS: { Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri); @@ -263,11 +247,11 @@ public class ViewKeyMainFragment extends Fragment implements // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) switch (loader.getId()) { - case LOADER_ID_KEYRING: + case LOADER_ID_USER_IDS: if (data.moveToFirst()) { // get name, email, and comment from USER_ID String[] mainUserId = PgpKeyHelper.splitUserId(data - .getString(KEYRING_INDEX_USER_ID)); + .getString(INDEX_UID_UID)); if (mainUserId[0] != null) { getActivity().setTitle(mainUserId[0]); mName.setText(mainUserId[0]); @@ -278,9 +262,6 @@ public class ViewKeyMainFragment extends Fragment implements mEmail.setText(mainUserId[1]); mComment.setText(mainUserId[2]); } - - break; - case LOADER_ID_USER_IDS: mUserIdsAdapter.swapCursor(data); break; case LOADER_ID_KEYS: @@ -354,9 +335,6 @@ public class ViewKeyMainFragment extends Fragment implements */ public void onLoaderReset(Loader loader) { switch (loader.getId()) { - case LOADER_ID_KEYRING: - // No resources need to be freed for this ID - break; case LOADER_ID_USER_IDS: mUserIdsAdapter.swapCursor(null); break; @@ -368,11 +346,11 @@ public class ViewKeyMainFragment extends Fragment implements } } - private void encryptToContact(Uri dataUri) { - long keyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri); + // TODO preselect from uri? should be feasible without trivial query + long keyId = Long.parseLong(dataUri.getPathSegments().get(1)); - long[] encryptionKeyIds = new long[]{keyId}; + long[] encryptionKeyIds = new long[]{ keyId }; Intent intent = new Intent(getActivity(), EncryptActivity.class); intent.setAction(EncryptActivity.ACTION_ENCRYPT); intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java index 9d60c1530..adcb5619d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java @@ -41,7 +41,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter { private int mIndexKeyId; private int mIndexAlgorithm; private int mIndexKeySize; - private int mIndexIsMasterKey; + private int mIndexRank; private int mIndexCanCertify; private int mIndexCanEncrypt; private int mIndexCanSign; @@ -76,7 +76,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter { mIndexKeyId = cursor.getColumnIndexOrThrow(Keys.KEY_ID); mIndexAlgorithm = cursor.getColumnIndexOrThrow(Keys.ALGORITHM); mIndexKeySize = cursor.getColumnIndexOrThrow(Keys.KEY_SIZE); - mIndexIsMasterKey = cursor.getColumnIndexOrThrow(Keys.IS_MASTER_KEY); + mIndexRank = cursor.getColumnIndexOrThrow(Keys.RANK); mIndexCanCertify = cursor.getColumnIndexOrThrow(Keys.CAN_CERTIFY); mIndexCanEncrypt = cursor.getColumnIndexOrThrow(Keys.CAN_ENCRYPT); mIndexCanSign = cursor.getColumnIndexOrThrow(Keys.CAN_SIGN); @@ -103,7 +103,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter { keyId.setText(keyIdStr); keyDetails.setText("(" + algorithmStr + ")"); - if (cursor.getInt(mIndexIsMasterKey) != 1) { + if (cursor.getInt(mIndexRank) == 0) { masterKeyIcon.setVisibility(View.INVISIBLE); } else { masterKeyIcon.setVisibility(View.VISIBLE); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index 3ff88aa2b..cd15c4d2d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -98,6 +98,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { checkDeleteSecret = (CheckBox) inflateView.findViewById(R.id.checkDeleteSecret); builder.setTitle(R.string.warning); + /* TODO! redo //If only a single key has been selected if (keyRingRowIds.length == 1) { @@ -210,6 +211,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { dismiss(); } }); + */ return builder.create(); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java index 3c8b872b0..b8db470b4 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java @@ -116,10 +116,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor secretKey = null; alert.setMessage(R.string.passphrase_for_symmetric_encryption); } else { - // TODO: by master key id??? - secretKey = PgpKeyHelper.getMasterKey(ProviderHelper.getPGPSecretKeyRingByKeyId(activity, - secretKeyId)); - // secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId)); + secretKey = ProviderHelper.getPGPSecretKeyByKeyId(activity, secretKeyId); if (secretKey == null) { alert.setTitle(R.string.title_key_not_found); @@ -175,7 +172,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor return; } else { clickSecretKey = PgpKeyHelper.getKeyNum(ProviderHelper - .getPGPSecretKeyRingByKeyId(activity, secretKeyId), + .getPGPSecretKeyRingWithKeyId(activity, secretKeyId), curKeyIndex); curKeyIndex++; // does post-increment work like C? continue; -- cgit v1.2.3 From 11b08c4d985854ded125d5a43e8a13207dee393d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 3 Apr 2014 12:28:30 +0200 Subject: Cleanup DrawerActivity --- .../keychain/ui/DrawerActivity.java | 35 +++------------------- 1 file changed, 4 insertions(+), 31 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java index 17dce0221..463c99948 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java @@ -125,13 +125,11 @@ public class DrawerActivity extends ActionBarActivity { // so that it doesn't consume all the Back button presses mDrawerLayout.setFocusableInTouchMode(false); } - // if (savedInstanceState == null) { - // selectItem(0); - // } } /** * Uses startActivity to call the Intent of the given class + * * @param drawerItem the class of the drawer item you want to load. Based on Constants.DrawerItems.* */ public void callIntentForDrawerItem(Class drawerItem) { @@ -159,16 +157,6 @@ public class DrawerActivity extends ActionBarActivity { return super.onCreateOptionsMenu(menu); } - /* Called whenever we call invalidateOptionsMenu() */ - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - // If the nav drawer is open, hide action items related to the content - // view - boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); - // menu.findItem(R.id.action_websearch).setVisible(!drawerOpen); - return super.onPrepareOptionsMenu(menu); - } - @Override public boolean onOptionsItemSelected(MenuItem item) { // The action bar home/up action should open or close the drawer. @@ -191,26 +179,11 @@ public class DrawerActivity extends ActionBarActivity { default: return super.onOptionsItemSelected(item); } - - // Handle action buttons - // switch (item.getItemId()) { - // case R.id.action_websearch: - // // create intent to perform web search for this planet - // Intent intent = new Intent(Intent.ACTION_WEB_SEARCH); - // intent.putExtra(SearchManager.QUERY, getSupportActionBar().getTitle()); - // // catch event that there's no activity to handle intent - // if (intent.resolveActivity(getPackageManager()) != null) { - // startActivity(intent); - // } else { - // Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show(); - // } - // return true; - // default: - // return super.onOptionsItemSelected(item); - // } } - /* The click listener for ListView in the navigation drawer */ + /** + * The click listener for ListView in the navigation drawer + */ private class DrawerItemClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { -- cgit v1.2.3 From 2df4ccafb5cab2963bde1f2d54293b6c3579d0f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 3 Apr 2014 15:02:55 +0200 Subject: Implement ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN --- .../keychain/service/KeychainIntentService.java | 13 -- .../keychain/ui/DecryptFragment.java | 9 +- .../keychain/ui/DrawerActivity.java | 16 +- .../keychain/ui/EncryptAsymmetricFragment.java | 5 +- .../keychain/ui/ImportKeysActivity.java | 166 +++++++++------------ .../keychain/ui/ImportKeysServerFragment.java | 5 + .../keychain/ui/ViewKeyActivity.java | 31 ++-- .../ui/adapter/ImportKeysListServerLoader.java | 28 +++- 8 files changed, 141 insertions(+), 132 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index e9c949246..59f2db46b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -112,7 +112,6 @@ public class KeychainIntentService extends IntentService // possible targets: public static final int TARGET_BYTES = 1; public static final int TARGET_URI = 2; - public static final int TARGET_STREAM = 3; // encrypt public static final String ENCRYPT_SIGNATURE_KEY_ID = "secret_key_id"; @@ -122,7 +121,6 @@ public class KeychainIntentService extends IntentService public static final String ENCRYPT_MESSAGE_BYTES = "message_bytes"; public static final String ENCRYPT_INPUT_FILE = "input_file"; public static final String ENCRYPT_OUTPUT_FILE = "output_file"; - public static final String ENCRYPT_PROVIDER_URI = "provider_uri"; public static final String ENCRYPT_SYMMETRIC_PASSPHRASE = "passphrase"; // decrypt/verify @@ -173,11 +171,7 @@ public class KeychainIntentService extends IntentService public static final String RESULT_KEY_USAGES = "new_key_usages"; // encrypt - public static final String RESULT_SIGNATURE_BYTES = "signature_data"; - public static final String RESULT_SIGNATURE_STRING = "signature_text"; - public static final String RESULT_ENCRYPTED_STRING = "encrypted_message"; public static final String RESULT_BYTES = "encrypted_data"; - public static final String RESULT_URI = "result_uri"; // decrypt/verify public static final String RESULT_DECRYPTED_BYTES = "decrypted_data"; @@ -191,10 +185,6 @@ public class KeychainIntentService extends IntentService // export public static final String RESULT_EXPORT = "exported"; - // query - public static final String RESULT_QUERY_KEY_DATA = "query_key_data"; - public static final String RESULT_QUERY_KEY_SEARCH_RESULT = "query_key_search_result"; - Messenger mMessenger; private boolean mIsCanceled; @@ -738,9 +728,6 @@ public class KeychainIntentService extends IntentService ArrayList entries = data.getParcelableArrayList(DOWNLOAD_KEY_LIST); String keyServer = data.getString(DOWNLOAD_KEY_SERVER); - // TODO: add extra which requires fingerprint suport and force verification! - // only supported by newer sks keyserver versions - // this downloads the keys and places them into the ImportKeysListEntry entries HkpKeyServer server = new HkpKeyServer(keyServer); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index fd7aef353..e7596534c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -38,6 +38,8 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; @@ -88,13 +90,9 @@ public class DecryptFragment extends Fragment { public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { - // this request is returned after LookupUnknownKeyDialogFragment started - // ImportKeysActivity and user looked uo key case RESULT_CODE_LOOKUP_KEY: { - Log.d(Constants.TAG, "Returning from Lookup Key..."); if (resultCode == Activity.RESULT_OK) { - // decrypt again -// decryptStart(); + // TODO: generate new OpenPgpSignatureResult and display it } return; } @@ -189,6 +187,7 @@ public class DecryptFragment extends Fragment { /** * Should be overridden by MessageFragment and FileFragment to start actual decryption + * * @param passphrase */ protected void decryptStart(String passphrase) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java index 463c99948..f81224380 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java @@ -151,6 +151,10 @@ public class DrawerActivity extends ActionBarActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { + if (mDrawerToggle == null) { + return super.onCreateOptionsMenu(menu); + } + menu.add(42, MENU_ID_PREFERENCE, 100, R.string.menu_preferences); menu.add(42, MENU_ID_HELP, 101, R.string.menu_help); @@ -159,6 +163,10 @@ public class DrawerActivity extends ActionBarActivity { @Override public boolean onOptionsItemSelected(MenuItem item) { + if (mDrawerToggle == null) { + return super.onOptionsItemSelected(item); + } + // The action bar home/up action should open or close the drawer. // ActionBarDrawerToggle will take care of this. if (mDrawerToggle.onOptionsItemSelected(item)) { @@ -216,14 +224,18 @@ public class DrawerActivity extends ActionBarActivity { protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. - mDrawerToggle.syncState(); + if (mDrawerToggle != null) { + mDrawerToggle.syncState(); + } } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Pass any configuration change to the drawer toggles - mDrawerToggle.onConfigurationChanged(newConfig); + if (mDrawerToggle != null) { + mDrawerToggle.onConfigurationChanged(newConfig); + } } private class NavItem { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index 4387f3d53..ca97e2867 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -252,7 +252,6 @@ public class EncryptAsymmetricFragment extends Fragment { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { - case RESULT_CODE_PUBLIC_KEYS: { if (resultCode == Activity.RESULT_OK) { Bundle bundle = data.getExtras(); @@ -273,11 +272,11 @@ public class EncryptAsymmetricFragment extends Fragment { } default: { + super.onActivityResult(requestCode, resultCode, data); + break; } } - - super.onActivityResult(requestCode, resultCode, data); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index b09fa4a4d..14726863a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui; import android.annotation.SuppressLint; +import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; @@ -34,8 +35,10 @@ import android.support.v7.app.ActionBar; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; + import com.beardedhen.androidbootstrap.BootstrapButton; import com.devspark.appmsg.AppMsg; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; @@ -54,7 +57,6 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa + "IMPORT_KEY_FROM_QR_CODE"; public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_KEYSERVER"; - // TODO: implement: public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_KEY_SERVER_AND_RETURN"; @@ -86,7 +88,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa ImportKeysNFCFragment.class }; - private int mCurrentNavPostition = -1; + private int mCurrentNavPosition = -1; @Override protected void onCreate(Bundle savedInstanceState) { @@ -104,15 +106,20 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa getSupportActionBar().setDisplayShowTitleEnabled(false); - setupDrawerNavigation(savedInstanceState); - - // set drop down navigation mNavigationStrings = getResources().getStringArray(R.array.import_action_list); - Context context = getSupportActionBar().getThemedContext(); - ArrayAdapter navigationAdapter = ArrayAdapter.createFromResource(context, - R.array.import_action_list, android.R.layout.simple_spinner_dropdown_item); - getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); - getSupportActionBar().setListNavigationCallbacks(navigationAdapter, this); + + if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) { + getSupportActionBar().setTitle(R.string.nav_import); + } else { + setupDrawerNavigation(savedInstanceState); + + // set drop down navigation + Context context = getSupportActionBar().getThemedContext(); + ArrayAdapter navigationAdapter = ArrayAdapter.createFromResource(context, + R.array.import_action_list, android.R.layout.simple_spinner_dropdown_item); + getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); + getSupportActionBar().setListNavigationCallbacks(navigationAdapter, this); + } handleActions(savedInstanceState, getIntent()); } @@ -152,34 +159,47 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa // action: directly load data startListFragment(savedInstanceState, importData, null, null); } - } else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action)) { - String query = null; - if (extras.containsKey(EXTRA_QUERY)) { - query = extras.getString(EXTRA_QUERY); - } else if (extras.containsKey(EXTRA_KEY_ID)) { - long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0); - if (keyId != 0) { - query = PgpKeyHelper.convertKeyIdToHex(keyId); + } else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action) + || ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(action)) { + if (extras.containsKey(EXTRA_QUERY) || extras.containsKey(EXTRA_KEY_ID)) { + /* simple search based on query or key id */ + + String query = null; + if (extras.containsKey(EXTRA_QUERY)) { + query = extras.getString(EXTRA_QUERY); + } else if (extras.containsKey(EXTRA_KEY_ID)) { + long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0); + if (keyId != 0) { + query = PgpKeyHelper.convertKeyIdToHex(keyId); + } + } + + if (query != null && query.length() > 0) { + // display keyserver fragment with query + Bundle args = new Bundle(); + args.putString(ImportKeysServerFragment.ARG_QUERY, query); + loadNavFragment(0, args); + + // action: search immediately + startListFragment(savedInstanceState, null, null, query); + } else { + Log.e(Constants.TAG, "Query is empty!"); + return; } } else if (extras.containsKey(EXTRA_FINGERPRINT)) { + /* + * search based on fingerprint, here we can enforce a check in the end + * if the right key has been downloaded + */ + String fingerprint = intent.getStringExtra(EXTRA_FINGERPRINT); - if (fingerprint != null) { - query = "0x" + fingerprint; - } + loadFromFingerprint(savedInstanceState, fingerprint); } else { Log.e(Constants.TAG, - "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query', 'key_id', or " + - "'fingerprint' extra!"); + "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query', 'key_id', or " + + "'fingerprint' extra!"); return; } - - // display keyserver fragment with query - Bundle args = new Bundle(); - args.putString(ImportKeysServerFragment.ARG_QUERY, query); - loadNavFragment(0, args); - - // action: search immediately - startListFragment(savedInstanceState, null, null, query); } else if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) { // NOTE: this only displays the appropriate fragment, no actions are taken @@ -234,14 +254,14 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa * onNavigationItemSelected() should check whether the Fragment is already in existence * inside your Activity." *

        - * from http://bit.ly/1dBYThO + * from http://stackoverflow.com/a/14295474 *

        * In our case, if we start ImportKeysActivity with parameters to directly search using a fingerprint, * the fragment would be loaded twice resulting in the query being empty after the second load. *

        * Our solution: * To prevent that a fragment will be loaded again even if it was already loaded loadNavFragment - * checks against mCurrentNavPostition. + * checks against mCurrentNavPosition. * * @param itemPosition * @param itemId @@ -257,10 +277,12 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa } private void loadNavFragment(int itemPosition, Bundle args) { - if (mCurrentNavPostition != itemPosition) { - getSupportActionBar().setSelectedNavigationItem(itemPosition); + if (mCurrentNavPosition != itemPosition) { + if (ActionBar.NAVIGATION_MODE_LIST == getSupportActionBar().getNavigationMode()) { + getSupportActionBar().setSelectedNavigationItem(itemPosition); + } loadFragment(NAVIGATION_CLASSES[itemPosition], args, mNavigationStrings[itemPosition]); - mCurrentNavPostition = itemPosition; + mCurrentNavPosition = itemPosition; } } @@ -280,7 +302,11 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa Log.d(Constants.TAG, "fingerprint: " + fingerprint); - if (fingerprint.length() < 16) { + loadFromFingerprint(savedInstanceState, fingerprint); + } + + public void loadFromFingerprint(Bundle savedInstanceState, String fingerprint) { + if (fingerprint == null || fingerprint.length() < 40) { AppMsg.makeText(this, R.string.import_qr_code_too_short_fingerprint, AppMsg.STYLE_ALERT).show(); return; @@ -291,6 +317,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa // display keyserver fragment with query Bundle args = new Bundle(); args.putString(ImportKeysServerFragment.ARG_QUERY, query); + args.putBoolean(ImportKeysServerFragment.ARG_DISABLE_QUERY_EDIT, true); loadNavFragment(0, args); // action: search directly @@ -301,66 +328,6 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa mListFragment.loadNew(importData, dataUri, serverQuery, keyServer); } - // private void importAndSignOld(final long keyId, final String expectedFingerprint) { - // if (expectedFingerprint != null && expectedFingerprint.length() > 0) { - // - // Thread t = new Thread() { - // @Override - // public void run() { - // try { - // // TODO: display some sort of spinner here while the user waits - // - // // TODO: there should be only 1 - // HkpKeyServer server = new HkpKeyServer(mPreferences.getKeyServers()[0]); - // String encodedKey = server.get(keyId); - // - // PGPKeyRing keyring = PGPHelper.decodeKeyRing(new ByteArrayInputStream( - // encodedKey.getBytes())); - // if (keyring != null && keyring instanceof PGPPublicKeyRing) { - // PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring; - // - // // make sure the fingerprints match before we cache this thing - // String actualFingerprint = PGPHelper.convertFingerprintToHex(publicKeyRing - // .getPublicKey().getFingerprint()); - // if (expectedFingerprint.equals(actualFingerprint)) { - // // store the signed key in our local cache - // int retval = PGPMain.storeKeyRingInCache(publicKeyRing); - // if (retval != Id.return_value.ok - // && retval != Id.return_value.updated) { - // status.putString(EXTRA_ERROR, - // "Failed to store signed key in local cache"); - // } else { - // Intent intent = new Intent(ImportFromQRCodeActivity.this, - // SignKeyActivity.class); - // intent.putExtra(EXTRA_KEY_ID, keyId); - // startActivityForResult(intent, Id.request.sign_key); - // } - // } else { - // status.putString( - // EXTRA_ERROR, - // "Scanned fingerprint does NOT match the fingerprint of the received key. " + - // "You shouldnt trust this key."); - // } - // } - // } catch (QueryException e) { - // Log.e(TAG, "Failed to query KeyServer", e); - // status.putString(EXTRA_ERROR, "Failed to query KeyServer"); - // status.putInt(Constants.extras.STATUS, Id.message.done); - // } catch (IOException e) { - // Log.e(TAG, "Failed to query KeyServer", e); - // status.putString(EXTRA_ERROR, "Failed to query KeyServer"); - // status.putInt(Constants.extras.STATUS, Id.message.done); - // } - // } - // }; - // - // t.setName("KeyExchange Download Thread"); - // t.setDaemon(true); - // t.start(); - // } - // } - - /** * Import keys with mImportData */ @@ -405,6 +372,11 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa BadImportKeyDialogFragment.newInstance(bad); badImportKeyDialogFragment.show(getSupportFragmentManager(), "badKeyDialog"); } + + if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) { + ImportKeysActivity.this.setResult(Activity.RESULT_OK); + finish(); + } } } }; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java index 0b2fff64e..3eb463dac 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java @@ -40,6 +40,7 @@ import org.sufficientlysecure.keychain.util.Log; public class ImportKeysServerFragment extends Fragment { public static final String ARG_QUERY = "query"; public static final String ARG_KEY_SERVER = "key_server"; + public static final String ARG_DISABLE_QUERY_EDIT = "disable_query_edit"; private ImportKeysActivity mImportActivity; @@ -140,6 +141,10 @@ public class ImportKeysServerFragment extends Fragment { Log.d(Constants.TAG, "keyServer: " + keyServer); } + + if (getArguments().getBoolean(ARG_DISABLE_QUERY_EDIT, false)) { + mQueryEditText.setEnabled(false); + } } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index b8b2e271f..e16ffcfdb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui; +import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -163,18 +164,13 @@ public class ViewKeyActivity extends ActionBarActivity { } private void updateFromKeyserver(Uri dataUri) { - long updateKeyId = ProviderHelper.getMasterKeyId(ViewKeyActivity.this, dataUri); - - if (updateKeyId == 0) { - Log.e(Constants.TAG, "this shouldn't happen. KeyId == 0!"); - return; - } + byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri); + String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); Intent queryIntent = new Intent(this, ImportKeysActivity.class); - queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER); - queryIntent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, updateKeyId); + queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN); + queryIntent.putExtra(ImportKeysActivity.EXTRA_FINGERPRINT, fingerprint); - // TODO: lookup with onactivityresult! startActivityForResult(queryIntent, RESULT_CODE_LOOKUP_KEY); } @@ -245,4 +241,21 @@ public class ViewKeyActivity extends ActionBarActivity { mExportHelper.deleteKey(dataUri, returnHandler); } + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case RESULT_CODE_LOOKUP_KEY: { + if (resultCode == Activity.RESULT_OK) { + // TODO: reload key??? move this into fragment? + } + break; + } + + default: { + super.onActivityResult(requestCode, resultCode, data); + + break; + } + } + } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java index a4dd06e40..259e14319 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui.adapter; import android.content.Context; import android.support.v4.content.AsyncTaskLoader; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.util.HkpKeyServer; import org.sufficientlysecure.keychain.util.KeyServer; @@ -53,7 +54,12 @@ public class ImportKeysListServerLoader return mEntryListWrapper; } - queryServer(mServerQuery, mKeyServer); + if (mServerQuery.startsWith("0x") && mServerQuery.length() == 42) { + Log.d(Constants.TAG, "This search is based on a unique fingerprint. Enforce a fingerprint check!"); + queryServer(mServerQuery, mKeyServer, true); + } else { + queryServer(mServerQuery, mKeyServer, false); + } return mEntryListWrapper; } @@ -84,14 +90,30 @@ public class ImportKeysListServerLoader /** * Query keyserver */ - private void queryServer(String query, String keyServer) { + private void queryServer(String query, String keyServer, boolean enforceFingerprint) { HkpKeyServer server = new HkpKeyServer(keyServer); try { ArrayList searchResult = server.search(query); mEntryList.clear(); // add result to data - mEntryList.addAll(searchResult); + if (enforceFingerprint) { + String fingerprint = query.substring(2); + Log.d(Constants.TAG, "fingerprint: " + fingerprint); + // query must return only one result! + if (searchResult.size() > 0) { + ImportKeysListEntry uniqueEntry = searchResult.get(0); + /* + * set fingerprint explicitly after query + * to enforce a check when the key is imported by KeychainIntentService + */ + uniqueEntry.setFingerPrintHex(fingerprint); + uniqueEntry.setSelected(true); + mEntryList.add(uniqueEntry); + } + } else { + mEntryList.addAll(searchResult); + } mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, null); } catch (KeyServer.InsufficientQuery e) { Log.e(Constants.TAG, "InsufficientQuery", e); -- cgit v1.2.3 From 09411a62fab849c345033a5d14d1e629855209df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 3 Apr 2014 15:16:13 +0200 Subject: Key lookup for API --- .../sufficientlysecure/keychain/remote/OpenPgpService.java | 10 +++++----- .../sufficientlysecure/keychain/ui/ImportKeysActivity.java | 13 +++++++++++-- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 18bb92552..9cdd16e23 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -39,6 +39,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity; import org.sufficientlysecure.keychain.service.PassphraseCacheService; +import org.sufficientlysecure.keychain.ui.ImportKeysActivity; import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; @@ -315,11 +316,10 @@ public class OpenPgpService extends RemoteService { if (signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY) { // If signature is unknown we return an _additional_ PendingIntent // to retrieve the missing key - // TODO!!! - Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); - intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE); - intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo"); - intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); + Intent intent = new Intent(getBaseContext(), ImportKeysActivity.class); + intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN); + intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, signatureResult.getKeyId()); + intent.putExtra(ImportKeysActivity.EXTRA_PENDING_INTENT_DATA, data); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, intent, diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 14726863a..6839d5a6e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -74,6 +74,10 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa public static final String EXTRA_KEY_ID = "key_id"; public static final String EXTRA_FINGERPRINT = "fingerprint"; + // only used by ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN when used from OpenPgpService + public static final String EXTRA_PENDING_INTENT_DATA = "data"; + private Intent mPendingIntentData; + // view private ImportKeysListFragment mListFragment; private String[] mNavigationStrings; @@ -109,7 +113,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa mNavigationStrings = getResources().getStringArray(R.array.import_action_list); if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) { - getSupportActionBar().setTitle(R.string.nav_import); + setTitle(R.string.nav_import); } else { setupDrawerNavigation(savedInstanceState); @@ -161,6 +165,11 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa } } else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action) || ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(action)) { + + // only used for OpenPgpService + if (extras.containsKey(EXTRA_PENDING_INTENT_DATA)) { + mPendingIntentData = extras.getParcelable(EXTRA_PENDING_INTENT_DATA); + } if (extras.containsKey(EXTRA_QUERY) || extras.containsKey(EXTRA_KEY_ID)) { /* simple search based on query or key id */ @@ -374,7 +383,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa } if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) { - ImportKeysActivity.this.setResult(Activity.RESULT_OK); + ImportKeysActivity.this.setResult(Activity.RESULT_OK, mPendingIntentData); finish(); } } -- cgit v1.2.3 From 04b0425d45574cdf86219898ea25ce15c33341a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 3 Apr 2014 15:18:05 +0200 Subject: Key lookup for API --- .../sufficientlysecure/keychain/remote/OpenPgpService.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 9cdd16e23..dc19bc5bb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -356,11 +356,10 @@ public class OpenPgpService extends RemoteService { // If keys are not in db we return an additional PendingIntent // to retrieve the missing key - // TODO!!! - Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); - intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE); - intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo"); - intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); + Intent intent = new Intent(getBaseContext(), ImportKeysActivity.class); + intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN); + intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, keyId); + intent.putExtra(ImportKeysActivity.EXTRA_PENDING_INTENT_DATA, data); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, intent, @@ -372,6 +371,9 @@ public class OpenPgpService extends RemoteService { } else { Intent result = new Intent(); result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); + + // TODO: also return PendingIntent that opens the key view activity + return result; } } catch (Exception e) { -- cgit v1.2.3 From c3091c2b5dbe350d7f7ed122f13ee5770efe2c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 3 Apr 2014 15:19:49 +0200 Subject: Changelog --- .../java/org/sufficientlysecure/keychain/remote/OpenPgpService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index dc19bc5bb..fa673f695 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -373,7 +373,7 @@ public class OpenPgpService extends RemoteService { result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); // TODO: also return PendingIntent that opens the key view activity - + return result; } } catch (Exception e) { -- cgit v1.2.3 From b06f142c5046618d97737d3f7f482ca7198f24e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 3 Apr 2014 16:51:34 +0200 Subject: title for ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN --- .../java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 6839d5a6e..9b8b92136 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -108,13 +108,13 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa } }); - getSupportActionBar().setDisplayShowTitleEnabled(false); - mNavigationStrings = getResources().getStringArray(R.array.import_action_list); if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) { setTitle(R.string.nav_import); } else { + getSupportActionBar().setDisplayShowTitleEnabled(false); + setupDrawerNavigation(savedInstanceState); // set drop down navigation -- cgit v1.2.3 From 428e94bb57764729efa72887110194300e63b28e Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 3 Apr 2014 17:08:04 +0200 Subject: ditch useless PgpKeyHelper.getMasterKey methods --- .../keychain/pgp/PgpDecryptVerify.java | 8 +-- .../keychain/pgp/PgpKeyHelper.java | 28 --------- .../keychain/pgp/PgpSignEncrypt.java | 4 +- .../keychain/provider/ProviderHelper.java | 68 ++++------------------ .../keychain/service/PassphraseCacheService.java | 2 +- .../keychain/ui/EditKeyActivity.java | 9 ++- .../keychain/ui/EncryptAsymmetricFragment.java | 4 +- 7 files changed, 23 insertions(+), 100 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 11b87fc97..77edd353c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -241,7 +241,7 @@ public class PgpDecryptVerify { // TODO: improve this code! get master key directly! PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(mContext, encData.getKeyID()); - long masterKeyId = PgpKeyHelper.getMasterKey(secretKeyRing).getKeyID(); + long masterKeyId = secretKeyRing.getSecretKey().getKeyID(); Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID()); Log.d(Constants.TAG, "allowedKeyIds: " + mAllowedKeyIds); Log.d(Constants.TAG, "masterKeyId: " + masterKeyId); @@ -375,7 +375,7 @@ public class PgpDecryptVerify { PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId( mContext, signatureKeyId); if (signKeyRing != null) { - userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); + userId = PgpKeyHelper.getMainUserId(signKeyRing.getPublicKey()); } signatureResult.setUserId(userId); break; @@ -559,7 +559,7 @@ public class PgpDecryptVerify { PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(mContext, signatureKeyId); if (signKeyRing != null) { - userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); + userId = PgpKeyHelper.getMainUserId(signKeyRing.getPublicKey()); } signatureResult.setUserId(userId); break; @@ -624,7 +624,7 @@ public class PgpDecryptVerify { signatureKeyId); PGPPublicKey mKey = null; if (signKeyRing != null) { - mKey = PgpKeyHelper.getMasterKey(signKeyRing); + mKey = signKeyRing.getPublicKey(); } if (signature.getKeyID() != mKey.getKeyID()) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index 290c8870b..9a97bc717 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -60,34 +60,6 @@ public class PgpKeyHelper { return key.getPublicKey().getCreationTime(); } - @SuppressWarnings("unchecked") - public static PGPPublicKey getMasterKey(PGPPublicKeyRing keyRing) { - if (keyRing == null) { - return null; - } - for (PGPPublicKey key : new IterableIterator(keyRing.getPublicKeys())) { - if (key.isMasterKey()) { - return key; - } - } - - return null; - } - - @SuppressWarnings("unchecked") - public static PGPSecretKey getMasterKey(PGPSecretKeyRing keyRing) { - if (keyRing == null) { - return null; - } - for (PGPSecretKey key : new IterableIterator(keyRing.getSecretKeys())) { - if (key.isMasterKey()) { - return key; - } - } - - return null; - } - @SuppressWarnings("unchecked") public static PGPSecretKey getKeyNum(PGPSecretKeyRing keyRing, long num) { long cnt = 0; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java index c1baed402..a864a165d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -306,7 +306,7 @@ public class PgpSignEncrypt { signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); signatureGenerator.init(signatureType, signaturePrivateKey); - String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signingKeyRing)); + String userId = PgpKeyHelper.getMainUserId(signingKeyRing.getSecretKey()); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); spGen.setSignerUserID(false, userId); signatureGenerator.setHashedSubpackets(spGen.generate()); @@ -505,7 +505,7 @@ public class PgpSignEncrypt { signatureGenerator.init(type, signaturePrivateKey); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); - String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signingKeyRing)); + String userId = PgpKeyHelper.getMainUserId(signingKeyRing.getSecretKey()); spGen.setSignerUserID(false, userId); signatureGenerator.setHashedSubpackets(spGen.generate()); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 3f96a51ef..3a0d910c5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -260,30 +260,6 @@ public class ProviderHelper { return ContentProviderOperation.newInsert(uri).withValues(values).build(); } - /** - * Private helper method - */ - private static ArrayList getKeyRingsMasterKeyIds(Context context, Uri queryUri) { - Cursor cursor = context.getContentResolver().query(queryUri, - new String[]{KeyRings.MASTER_KEY_ID}, null, null, null); - - ArrayList masterKeyIds = new ArrayList(); - if (cursor != null) { - int masterKeyIdCol = cursor.getColumnIndex(KeyRings.MASTER_KEY_ID); - if (cursor.moveToFirst()) { - do { - masterKeyIds.add(cursor.getLong(masterKeyIdCol)); - } while (cursor.moveToNext()); - } - } - - if (cursor != null) { - cursor.close(); - } - - return masterKeyIds; - } - public static void deletePublicKeyRing(Context context, long masterKeyId) { ContentResolver cr = context.getContentResolver(); cr.delete(KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null); @@ -294,38 +270,6 @@ public class ProviderHelper { cr.delete(KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId)), null, null); } - public static boolean getMasterKeyCanCertify(Context context, Uri queryUri) { - // TODO redo - - return false; - - /* - String[] projection = new String[]{ - KeyRings.MASTER_KEY_ID, - "(SELECT COUNT(sign_keys." + Keys._ID + ") FROM " + Tables.KEYS - + " AS sign_keys WHERE sign_keys." + Keys.KEY_RING_ROW_ID + " = " - + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID - + " AND sign_keys." + Keys.CAN_CERTIFY + " = '1' AND " + Keys.IS_MASTER_KEY - + " = 1) AS sign",}; - - ContentResolver cr = context.getContentResolver(); - Cursor cursor = cr.query(queryUri, projection, null, null, null); - - long masterKeyId = -1; - if (cursor != null && cursor.moveToFirst()) { - int masterKeyIdCol = cursor.getColumnIndex("sign"); - - masterKeyId = cursor.getLong(masterKeyIdCol); - } - - if (cursor != null) { - cursor.close(); - } - - return (masterKeyId > 0); - */ - } - public static boolean hasSecretKeyByMasterKeyId(Context context, long masterKeyId) { Uri queryUri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId)); // see if we can get our master key id back from the uri @@ -336,8 +280,16 @@ public class ProviderHelper { * Get master key id of key */ public static long getMasterKeyId(Context context, Uri queryUri) { - String[] projection = new String[]{KeyRings.MASTER_KEY_ID}; - Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null); + // try extracting from the uri first + try { + return Long.parseLong(queryUri.getPathSegments().get(1)); + } catch(NumberFormatException e) { + // didn't work? oh well. + } + + Cursor cursor = context.getContentResolver().query(queryUri, new String[] { + KeyRings.MASTER_KEY_ID + }, null, null, null); long masterKeyId = 0; try { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index 63703a02b..0ec4c1239 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -174,7 +174,7 @@ public class PassphraseCacheService extends Service { if (keyRing == null) { return null; } - PGPSecretKey masterKey = PgpKeyHelper.getMasterKey(keyRing); + PGPSecretKey masterKey = keyRing.getSecretKey(); if (masterKey == null) { return null; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index d7ff8c207..0caf60aa1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -276,8 +276,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener // get master key id using row id long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri); - - mMasterCanSign = ProviderHelper.getMasterKeyCanCertify(this, mDataUri); finallyEdit(masterKeyId); } } @@ -347,8 +345,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } return true; case R.id.menu_key_edit_delete: - long rowId= ProviderHelper.getRowId(this,mDataUri); - Uri convertUri = KeychainContract.KeyRings.buildSecretKeyRingUri(Long.toString(rowId)); + Uri convertUri = KeychainContract.KeyRings.buildSecretKeyRingUri(mDataUri); // Message is received after key is deleted Handler returnHandler = new Handler() { @Override @@ -374,7 +371,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener PGPSecretKey masterKey = null; mKeyRing = ProviderHelper.getPGPSecretKeyRing(this, masterKeyId); if (mKeyRing != null) { - masterKey = PgpKeyHelper.getMasterKey(mKeyRing); + masterKey = mKeyRing.getSecretKey(); + mMasterCanSign = PgpKeyHelper.isCertificationKey(mKeyRing.getSecretKey()); for (PGPSecretKey key : new IterableIterator(mKeyRing.getSecretKeys())) { mKeys.add(key); mKeysUsages.add(-1); // get usage when view is created @@ -382,6 +380,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } else { Log.e(Constants.TAG, "Keyring not found with masterKeyId: " + masterKeyId); Toast.makeText(this, R.string.error_no_secret_key_found, Toast.LENGTH_LONG).show(); + // TODO } if (masterKey != null) { boolean isSet = false; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index 6b0e1d9f1..a8de40c70 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -145,7 +145,7 @@ public class EncryptAsymmetricFragment extends Fragment { preselectedSignatureKeyId); PGPSecretKey masterKey; if (keyRing != null) { - masterKey = PgpKeyHelper.getMasterKey(keyRing); + masterKey = keyRing.getSecretKey(); if (masterKey != null) { Vector signKeys = PgpKeyHelper.getUsableSigningKeys(keyRing); if (signKeys.size() > 0) { @@ -166,7 +166,7 @@ public class EncryptAsymmetricFragment extends Fragment { if (keyRing == null) { continue; } - masterKey = PgpKeyHelper.getMasterKey(keyRing); + masterKey = keyRing.getPublicKey(); if (masterKey == null) { continue; } -- cgit v1.2.3 From dedcfd8a7243a8ff5740ad706bc749d57ee8b5e8 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 3 Apr 2014 17:09:26 +0200 Subject: more work on streamlining uris, and stripping ProviderHelper --- .../keychain/provider/KeychainProvider.java | 5 + .../keychain/provider/ProviderHelper.java | 134 +++++++++------------ .../remote/ui/AccountSettingsFragment.java | 6 +- .../keychain/ui/EncryptAsymmetricFragment.java | 23 ++-- .../keychain/ui/KeyListFragment.java | 27 ++--- .../keychain/ui/ViewKeyActivity.java | 13 +- .../keychain/ui/ViewKeyActivityJB.java | 19 ++- .../keychain/ui/ViewKeyMainFragment.java | 4 - .../ui/dialog/DeleteKeyDialogFragment.java | 125 ++++++------------- .../ui/dialog/ShareQrCodeDialogFragment.java | 15 ++- 10 files changed, 148 insertions(+), 223 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 39ea083fa..a4fd1130d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -256,6 +256,9 @@ public class KeychainProvider extends ContentProvider { + Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; } + // uri to watch is all /key_rings/ + uri = KeyRings.CONTENT_URI; + break; } /*case SECRET_KEY_RING_BY_EMAILS: @@ -503,6 +506,7 @@ public class KeychainProvider extends ContentProvider { } // corresponding keys and userIds are deleted by ON DELETE CASCADE count = db.delete(Tables.KEY_RINGS_PUBLIC, selection, selectionArgs); + uri = KeyRings.buildGenericKeyRingUri(uri.getPathSegments().get(1)); break; } case KEY_RING_SECRET: { @@ -512,6 +516,7 @@ public class KeychainProvider extends ContentProvider { selection += " AND (" + additionalSelection + ")"; } count = db.delete(Tables.KEY_RINGS_SECRET, selection, selectionArgs); + uri = KeyRings.buildGenericKeyRingUri(uri.getPathSegments().get(1)); break; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 3a0d910c5..18eaa375a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -23,7 +23,10 @@ import android.content.ContentValues; import android.content.Context; import android.content.OperationApplicationException; import android.database.Cursor; +import android.database.CursorWindow; +import android.database.CursorWrapper; import android.database.DatabaseUtils; +import android.database.sqlite.SQLiteCursor; import android.net.Uri; import android.os.RemoteException; @@ -42,7 +45,6 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; -import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.remote.AccountSettings; import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.util.IterableIterator; @@ -52,6 +54,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.Set; @@ -81,6 +84,57 @@ public class ProviderHelper { return keyRing; } + public static Object getUnifiedData(Context context, long masterKeyId, String column) { + return getUnifiedData(context, masterKeyId, new String[] { column }).get(column); + } + public static Object getUnifiedData(Context context, Uri uri, String column) { + return getUnifiedData(context, uri, new String[] { column }).get(column); + } + + public static HashMap getUnifiedData(Context context, long masterKeyId, String[] proj) { + return getUnifiedData(context, KeyRings.buildGenericKeyRingUri(Long.toString(masterKeyId)), proj); + } + + public static HashMap getUnifiedData(Context context, Uri uri, String[] proj) { + uri = KeyRings.buildUnifiedKeyRingUri(uri); + + Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null); + + HashMap result = new HashMap(proj.length); + if (cursor != null && cursor.moveToFirst()) { + // this is a HACK because we don't have Cursor.getType (which is api level 11) + CursorWindow cursorWindow; + if(cursor instanceof CursorWrapper) { + cursorWindow = ((SQLiteCursor) ((CursorWrapper) cursor).getWrappedCursor()).getWindow(); + } else { + cursorWindow = ((SQLiteCursor) cursor).getWindow(); + } + + int pos = 0; + for(String p : proj) { + if (cursorWindow.isNull(0, pos)) { + result.put(p, cursor.isNull(pos)); + } else if (cursorWindow.isLong(0, pos)) { + result.put(p, cursor.getLong(pos)); + } else if (cursorWindow.isFloat(0, pos)) { + result.put(p, cursor.getFloat(pos)); + } else if (cursorWindow.isString(0, pos)) { + result.put(p, cursor.getString(pos)); + } else if (cursorWindow.isBlob(0, pos)) { + result.put(p, cursor.getBlob(pos)); + } + pos += 1; + } + } + + if (cursor != null) { + cursor.close(); + } + + return result; + } + + public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) { return getPGPPublicKeyRingWithKeyId(context, keyId).getPublicKey(keyId); } @@ -307,84 +361,6 @@ public class ProviderHelper { return masterKeyId; } - public static long getRowId(Context context, Uri queryUri) { - String[] projection = new String[]{KeyRings._ID}; - Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null); - - long rowId = 0; - try { - if (cursor != null && cursor.moveToFirst()) { - int idCol = cursor.getColumnIndexOrThrow(KeyRings._ID); - - rowId = cursor.getLong(idCol); - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - return rowId; - } - - /** - * Get fingerprint of key - */ - public static byte[] getFingerprint(Context context, Uri queryUri) { - String[] projection = new String[]{Keys.FINGERPRINT}; - Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null); - - byte[] fingerprint = null; - try { - if (cursor != null && cursor.moveToFirst()) { - int col = cursor.getColumnIndexOrThrow(Keys.FINGERPRINT); - - fingerprint = cursor.getBlob(col); - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - // FALLBACK: If fingerprint is not in database, get it from key blob! - // this could happen if the key was saved by a previous version of Keychain! - if (fingerprint == null) { - Log.d(Constants.TAG, "FALLBACK: fingerprint is not in database, get it from key blob!"); - - // get master key id - projection = new String[]{KeyRings.MASTER_KEY_ID}; - cursor = context.getContentResolver().query(queryUri, projection, null, null, null); - long masterKeyId = 0; - try { - if (cursor != null && cursor.moveToFirst()) { - int col = cursor.getColumnIndexOrThrow(KeyRings.MASTER_KEY_ID); - - masterKeyId = cursor.getLong(col); - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - PGPPublicKey key = ProviderHelper.getPGPPublicKeyRing(context, masterKeyId).getPublicKey(); - // if it is no public key get it from your own keys... - if (key == null) { - PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId).getSecretKey(); - if (secretKey == null) { - Log.e(Constants.TAG, "Key could not be found!"); - return null; - } - key = secretKey.getPublicKey(); - } - - fingerprint = key.getFingerprint(); - } - - return fingerprint; - } - public static ArrayList getKeyRingsAsArmoredString(Context context, Uri uri, long[] masterKeyIds) { ArrayList output = new ArrayList(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java index dee0dae95..992aa7c95 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java @@ -34,6 +34,7 @@ import com.beardedhen.androidbootstrap.BootstrapButton; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote.AccountSettings; import org.sufficientlysecure.keychain.ui.EditKeyActivity; import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; @@ -176,9 +177,8 @@ public class AccountSettingsFragment extends Fragment implements case REQUEST_CODE_CREATE_KEY: { if (resultCode == Activity.RESULT_OK) { // select newly created key - Uri newKeyUri = data.getData(); - // TODO helper method for this? - mSelectKeyFragment.selectKey(Long.parseLong(newKeyUri.getPathSegments().get(1))); + long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), data.getData()); + mSelectKeyFragment.selectKey(masterKeyId); } break; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index a8de40c70..0b724d52c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -37,8 +37,10 @@ import org.spongycastle.openpgp.PGPSecretKeyRing; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import java.util.HashMap; import java.util.Vector; public class EncryptAsymmetricFragment extends Fragment { @@ -202,20 +204,17 @@ public class EncryptAsymmetricFragment extends Fragment { } else { String uid = getResources().getString(R.string.user_id_no_name); String uidExtra = ""; - // TODO: don't use bouncy castle objects! - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(getActivity(), - mSecretKeyId); - if (keyRing != null) { - PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing); - if (key != null) { - String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key); - String chunks[] = userId.split(" <", 2); - uid = chunks[0]; - if (chunks.length > 1) { - uidExtra = "<" + chunks[1]; - } + // See if we can get a user_id from a unified query + Object data = ProviderHelper.getUnifiedData( + getActivity(), mSecretKeyId, KeychainContract.UserIds.USER_ID); + if(data instanceof String) { + String chunks[] = ((String) data).split(" <", 2); + uid = chunks[0]; + if (chunks.length > 1) { + uidExtra = "<" + chunks[1]; } } + mMainUserId.setText(uid); mMainUserIdRest.setText(uidExtra); mSign.setChecked(true); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 6dec5e56e..cc0abe48a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -193,28 +193,15 @@ public class KeyListFragment extends Fragment break; } case R.id.menu_key_list_multi_delete: { - ids = mStickyList.getWrappedList().getCheckedItemIds(); + ids = mAdapter.getCurrentSelectedMasterKeyIds(); showDeleteKeyDialog(mode, ids); break; } case R.id.menu_key_list_multi_export: { - ids = mStickyList.getWrappedList().getCheckedItemIds(); - long[] masterKeyIds = new long[2*ids.length]; - /* TODO! redo - ArrayList allPubRowIds = - ProviderHelper.getPublicKeyRingsRowIds(getActivity()); - for (int i = 0; i < ids.length; i++) { - if (allPubRowIds.contains(ids[i])) { - masterKeyIds[i] = - ProviderHelper.getPublicMasterKeyId(getActivity(), ids[i]); - } else { - masterKeyIds[i] = - ProviderHelper.getSecretMasterKeyId(getActivity(), ids[i]); - } - }*/ + ids = mAdapter.getCurrentSelectedMasterKeyIds(); ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity()); mExportHelper - .showExportKeysDialog(masterKeyIds, Id.type.public_key, + .showExportKeysDialog(ids, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB, getString(R.string.also_export_secret_keys)); break; @@ -343,7 +330,7 @@ public class KeyListFragment extends Fragment } viewIntent.setData( KeychainContract - .KeyRings.buildPublicKeyRingUri( + .KeyRings.buildGenericKeyRingUri( Long.toString(mAdapter.getMasterKeyId(position)))); startActivity(viewIntent); } @@ -362,11 +349,11 @@ public class KeyListFragment extends Fragment /** * Show dialog to delete key * - * @param keyRingRowIds + * @param masterKeyIds */ @TargetApi(11) // TODO: this method needs an overhaul to handle both public and secret keys gracefully! - public void showDeleteKeyDialog(final ActionMode mode, long[] keyRingRowIds) { + public void showDeleteKeyDialog(final ActionMode mode, long[] masterKeyIds) { // Message is received after key is deleted Handler returnHandler = new Handler() { @Override @@ -381,7 +368,7 @@ public class KeyListFragment extends Fragment Messenger messenger = new Messenger(returnHandler); DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger, - keyRingRowIds); + masterKeyIds); deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog"); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 54fd04b10..2437270e5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -173,10 +173,15 @@ public class ViewKeyActivity extends ActionBarActivity { private void shareKey(Uri dataUri, boolean fingerprintOnly) { String content; if (fingerprintOnly) { - byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri); - String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); - - content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint; + Object blob = ProviderHelper.getUnifiedData(this, dataUri, KeychainContract.Keys.FINGERPRINT); + if(blob instanceof byte[]) { + String fingerprint = PgpKeyHelper.convertFingerprintToHex((byte[]) blob); + content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint; + } else { + Toast.makeText(getApplicationContext(), "Bad key selected!", + Toast.LENGTH_LONG).show(); + return; + } } else { // get public keyring as ascii armored string long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java index 997ff9c7a..9bbbb6c7b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java @@ -34,6 +34,9 @@ import android.widget.Toast; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.util.Log; + +import java.io.IOException; @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMessageCallback, @@ -64,13 +67,17 @@ public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMess // get public keyring as byte array long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); - mSharedKeyringBytes = ProviderHelper.getKeyRingsAsByteArray(this, dataUri, - new long[]{masterKeyId}); + try { + mSharedKeyringBytes = ProviderHelper.getPGPPublicKeyRing(this, masterKeyId).getEncoded(); - // Register callback to set NDEF message - mNfcAdapter.setNdefPushMessageCallback(this, this); - // Register callback to listen for message-sent success - mNfcAdapter.setOnNdefPushCompleteCallback(this, this); + // Register callback to set NDEF message + mNfcAdapter.setNdefPushMessageCallback(this, this); + // Register callback to listen for message-sent success + mNfcAdapter.setOnNdefPushCompleteCallback(this, this); + } catch(IOException e) { + // not much trouble, but leave a note + Log.e(Constants.TAG, "Error parsing keyring: ", e); + } } } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index 703f7e861..75853ac2a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -298,10 +298,6 @@ public class ViewKeyMainFragment extends Fragment implements mAlgorithm.setText(algorithmStr); byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT); - if (fingerprintBlob == null) { - // FALLBACK for old database entries - fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), mDataUri); - } String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); mFingerprint.setText(PgpKeyHelper.colorizeFingerprint(fingerprint)); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index 9427ce0db..57dbb7794 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -43,10 +43,11 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.Log; import java.util.ArrayList; +import java.util.HashMap; public class DeleteKeyDialogFragment extends DialogFragment { private static final String ARG_MESSENGER = "messenger"; - private static final String ARG_DELETE_KEY_RING_ROW_IDS = "delete_key_ring_row_ids"; + private static final String ARG_DELETE_MASTER_KEY_IDS = "delete_master_key_ids"; public static final int MESSAGE_OKAY = 1; public static final int MESSAGE_ERROR = 0; @@ -63,13 +64,13 @@ public class DeleteKeyDialogFragment extends DialogFragment { /** * Creates new instance of this delete file dialog fragment */ - public static DeleteKeyDialogFragment newInstance(Messenger messenger, long[] keyRingRowIds - ) { + public static DeleteKeyDialogFragment newInstance(Messenger messenger, + long[] masterKeyIds) { DeleteKeyDialogFragment frag = new DeleteKeyDialogFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_MESSENGER, messenger); - args.putLongArray(ARG_DELETE_KEY_RING_ROW_IDS, keyRingRowIds); + args.putLongArray(ARG_DELETE_MASTER_KEY_IDS, masterKeyIds); //We don't need the key type frag.setArguments(args); @@ -84,7 +85,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { final FragmentActivity activity = getActivity(); mMessenger = getArguments().getParcelable(ARG_MESSENGER); - final long[] keyRingRowIds = getArguments().getLongArray(ARG_DELETE_KEY_RING_ROW_IDS); + final long[] masterKeyIds = getArguments().getLongArray(ARG_DELETE_MASTER_KEY_IDS); AlertDialog.Builder builder = new AlertDialog.Builder(activity); @@ -98,35 +99,29 @@ public class DeleteKeyDialogFragment extends DialogFragment { mCheckDeleteSecret = (CheckBox) mInflateView.findViewById(R.id.checkDeleteSecret); builder.setTitle(R.string.warning); - /* TODO! redo - //If only a single key has been selected - if (keyRingRowIds.length == 1) { - Uri dataUri; - ArrayList publicKeyRings; //Any one will do + // If only a single key has been selected + if (masterKeyIds.length == 1) { mIsSingleSelection = true; - long selectedRow = keyRingRowIds[0]; - long keyType; - publicKeyRings = ProviderHelper.getPublicKeyRingsRowIds(activity); - - if (publicKeyRings.contains(selectedRow)) { - //TODO Should be a better method to do this other than getting all the KeyRings - dataUri = KeychainContract.KeyRings.buildPublicKeyRingsUri(String.valueOf(selectedRow)); - keyType = Id.type.public_key; - } else { - dataUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(String.valueOf(selectedRow)); - keyType = Id.type.secret_key; - } + long masterKeyId = masterKeyIds[0]; + + HashMap data = ProviderHelper.getUnifiedData(activity, masterKeyId, new String[]{ + KeychainContract.UserIds.USER_ID, + KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID + }); + String userId = (String) data.get(KeychainContract.UserIds.USER_ID); + boolean hasSecret = data.get( + KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID + ) instanceof Long; - String userId = ProviderHelper.getUserId(activity, dataUri); - // Hide the Checkbox and TextView since this is a single selection, - // user will be notified thru message + // Hide the Checkbox and TextView since this is a single selection,user will be notified through message mDeleteSecretKeyView.setVisibility(View.GONE); // Set message depending on which key it is. - mMainMessage.setText(getString(keyType == Id.type.secret_key ? - R.string.secret_key_deletion_confirmation : - R.string.public_key_deletetion_confirmation, userId)); + mMainMessage.setText(getString( + hasSecret ? R.string.secret_key_deletion_confirmation + : R.string.public_key_deletetion_confirmation, + userId)); } else { mDeleteSecretKeyView.setVisibility(View.VISIBLE); mMainMessage.setText(R.string.key_deletion_confirmation_multi); @@ -137,75 +132,27 @@ public class DeleteKeyDialogFragment extends DialogFragment { builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - Uri queryUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri(); - String[] projection = new String[]{ - KeychainContract.KeyRings.MASTER_KEY_ID, // 0 - KeychainContract.KeyRings.TYPE// 1 - }; - - // make selection with all entries where _ID is one of the given row ids - String selection = KeychainDatabase.Tables.KEY_RINGS + "." + - KeychainContract.KeyRings._ID + " IN("; - String selectionIDs = ""; - for (int i = 0; i < keyRingRowIds.length; i++) { - selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'"; - if (i + 1 < keyRingRowIds.length) { - selectionIDs += ","; - } - } - selection += selectionIDs + ")"; - - Cursor cursor = activity.getContentResolver().query(queryUri, projection, - selection, null, null); - - - long masterKeyId; - long keyType; - boolean isSuccessfullyDeleted; - try { - isSuccessfullyDeleted = false; - while (cursor != null && cursor.moveToNext()) { - masterKeyId = cursor.getLong(0); - keyType = cursor.getLong(1); - - Log.d(Constants.TAG, "masterKeyId: " + masterKeyId + - ", keyType:" + - (keyType == KeychainContract.KeyTypes.PUBLIC ? - "Public" : "Private")); - - if (keyType == KeychainContract.KeyTypes.SECRET) { - if (mCheckDeleteSecret.isChecked() || mIsSingleSelection) { - ProviderHelper.deleteUnifiedKeyRing(activity, - String.valueOf(masterKeyId), true); - } - } else { - ProviderHelper.deleteUnifiedKeyRing(activity, - String.valueOf(masterKeyId), false); - } - } - - //Check if the selected rows have actually been deleted - cursor = activity.getContentResolver().query( - queryUri, projection, selection, null, null); - if (cursor == null || cursor.getCount() == 0 || - !mCheckDeleteSecret.isChecked()) { - isSuccessfullyDeleted = true; - } - } finally { - if (cursor != null) { - cursor.close(); - } + + boolean success = false; + for(long masterKeyId : masterKeyIds) { + int count = activity.getContentResolver().delete( + KeychainContract.KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null + ); + if(count > 0) + success = true; } dismiss(); - if (isSuccessfullyDeleted) { + if (success) { sendMessageToHandler(MESSAGE_OKAY, null); } else { sendMessageToHandler(MESSAGE_ERROR, null); } } - }); + + } + ); builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override @@ -213,7 +160,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { dismiss(); } }); - */ + return builder.create(); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java index 18403837a..1b81c8b3b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java @@ -31,6 +31,7 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.QrCodeUtils; @@ -89,22 +90,24 @@ public class ShareQrCodeDialogFragment extends DialogFragment { if (mFingerprintOnly) { alert.setPositiveButton(R.string.btn_okay, null); - byte[] fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), dataUri); - String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); + Object blob = ProviderHelper.getUnifiedData(getActivity(), dataUri, KeychainContract.Keys.FINGERPRINT); + if(!(blob instanceof byte[])) { + // TODO error handling?! + return null; + } + String fingerprint = PgpKeyHelper.convertFingerprintToHex((byte[]) blob); mText.setText(getString(R.string.share_qr_code_dialog_fingerprint_text) + " " + fingerprint); - content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint; setQrCode(content); } else { mText.setText(R.string.share_qr_code_dialog_start); - // TODO + // TODO works, but long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri); - // get public keyring as ascii armored string ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString( - getActivity(), dataUri, new long[]{masterKeyId}); + getActivity(), dataUri, new long[] { masterKeyId }); // TODO: binary? -- cgit v1.2.3 From 2620e0bfc8cbbdfb304629dbcf8d3a9d2d0b35ae Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 3 Apr 2014 22:49:08 +0200 Subject: db-overhaul: more work on new provider specifics: - secret keys are preserved when a new public key is inserted - started work to give virtual columns a representation in the contract class - streamline ProviderHelper methods. the getUnifiedData method relies on a api level 11 method, not sure yet how to fix/workaround that... - many more small things work as they did before --- .../keychain/provider/KeychainContract.java | 36 +++-- .../keychain/provider/KeychainProvider.java | 139 +++++++++--------- .../keychain/provider/ProviderHelper.java | 159 +++++++-------------- .../keychain/service/KeychainIntentService.java | 4 +- .../keychain/ui/EditKeyActivity.java | 3 +- .../keychain/ui/KeyListFragment.java | 42 +++--- .../keychain/ui/ViewKeyActivity.java | 8 +- .../keychain/ui/ViewKeyMainFragment.java | 59 ++++---- .../ui/dialog/DeleteKeyDialogFragment.java | 19 +-- .../ui/dialog/ShareQrCodeDialogFragment.java | 2 +- 10 files changed, 208 insertions(+), 263 deletions(-) (limited to 'OpenPGP-Keychain/src/main/java') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index fcf8f7962..e6e106ba6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -96,18 +96,14 @@ public class KeychainContract { public static final String BASE_API_APPS = "api_apps"; public static final String PATH_ACCOUNTS = "accounts"; - public static class KeyRings implements KeyRingsColumns, BaseColumns { + public static class KeyRings implements BaseColumns, KeysColumns, UserIdsColumns { + public static final String MASTER_KEY_ID = "master_key_id"; + public static final String HAS_SECRET = "has_secret"; + public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() .appendPath(BASE_KEY_RINGS).build(); - /** - * Use if multiple items get returned - */ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.key_ring"; - - /** - * Use if a single item is returned - */ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.key_ring"; public static Uri buildUnifiedKeyRingsUri() { @@ -121,6 +117,24 @@ public class KeychainContract { return CONTENT_URI.buildUpon().appendPath(masterKeyId).build(); } + public static Uri buildUnifiedKeyRingUri(String masterKeyId) { + return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_UNIFIED).build(); + } + public static Uri buildUnifiedKeyRingUri(Uri uri) { + return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_UNIFIED).build(); + } + } + + public static class KeyRingData implements KeyRingsColumns, BaseColumns { + public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() + .appendPath(BASE_KEY_RINGS).build(); + + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.key_ring_data"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.key_ring_data"; + + public static Uri buildPublicKeyRingUri() { + return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).build(); + } public static Uri buildPublicKeyRingUri(String masterKeyId) { return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_PUBLIC).build(); } @@ -135,12 +149,6 @@ public class KeychainContract { return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_SECRET).build(); } - public static Uri buildUnifiedKeyRingUri(String masterKeyId) { - return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_UNIFIED).build(); - } - public static Uri buildUnifiedKeyRingUri(Uri uri) { - return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_UNIFIED).build(); - } } public static class Keys implements KeysColumns, BaseColumns { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index a4fd1130d..8b1ee4886 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -26,19 +26,15 @@ import android.database.sqlite.SQLiteConstraintException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; -import android.provider.BaseColumns; import android.text.TextUtils; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyTypes; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; -import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.util.Log; @@ -46,13 +42,9 @@ import java.util.Arrays; import java.util.HashMap; public class KeychainProvider extends ContentProvider { - // public static final String ACTION_BROADCAST_DATABASE_CHANGE = Constants.PACKAGE_NAME - // + ".action.DATABASE_CHANGE"; - // - // public static final String EXTRA_BROADCAST_KEY_TYPE = "key_type"; - // public static final String EXTRA_BROADCAST_CONTENT_ITEM_TYPE = "contentItemType"; private static final int KEY_RINGS_UNIFIED = 101; + private static final int KEY_RINGS_PUBLIC = 102; private static final int KEY_RING_UNIFIED = 200; private static final int KEY_RING_KEYS = 201; @@ -79,18 +71,22 @@ public class KeychainProvider extends ContentProvider { String authority = KeychainContract.CONTENT_AUTHORITY; /** - * select from key_ring + * list key_rings * *

                  * key_rings/unified
        +         * key_rings/public
                  * 
        */ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_UNIFIED, KEY_RINGS_UNIFIED); + matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + + "/" + KeychainContract.PATH_PUBLIC, + KEY_RINGS_PUBLIC); /** - * select from key_ring + * list key_ring specifics * *
                  * key_rings/_/unified
        @@ -215,45 +211,44 @@ public class KeychainProvider extends ContentProvider {
                     case KEY_RING_UNIFIED:
                     case KEY_RINGS_UNIFIED: {
                         HashMap projectionMap = new HashMap();
        -                projectionMap.put(BaseColumns._ID, Tables.KEYS + ".oid AS _id");
        -                projectionMap.put(KeysColumns.MASTER_KEY_ID, Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID);
        -                projectionMap.put(KeysColumns.RANK, Tables.KEYS + "." + KeysColumns.RANK);
        -                projectionMap.put(KeysColumns.KEY_ID, KeysColumns.KEY_ID);
        -                projectionMap.put(KeysColumns.KEY_SIZE, KeysColumns.KEY_SIZE);
        -                projectionMap.put(KeysColumns.IS_REVOKED, KeysColumns.IS_REVOKED);
        -                projectionMap.put(KeysColumns.CAN_CERTIFY, KeysColumns.CAN_CERTIFY);
        -                projectionMap.put(KeysColumns.CAN_ENCRYPT, KeysColumns.CAN_ENCRYPT);
        -                projectionMap.put(KeysColumns.CAN_SIGN, KeysColumns.CAN_SIGN);
        -                projectionMap.put(KeysColumns.CREATION, KeysColumns.CREATION);
        -                projectionMap.put(KeysColumns.EXPIRY, KeysColumns.EXPIRY);
        -                projectionMap.put(KeysColumns.ALGORITHM, KeysColumns.ALGORITHM);
        -                projectionMap.put(KeysColumns.FINGERPRINT, KeysColumns.FINGERPRINT);
        -                projectionMap.put(UserIdsColumns.USER_ID, UserIdsColumns.USER_ID);
        -                projectionMap.put(Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID, Tables.KEY_RINGS_SECRET + "." + KeyRingsColumns.MASTER_KEY_ID);
        +                projectionMap.put(KeyRings._ID, Tables.KEYS + ".oid AS _id");
        +                projectionMap.put(KeyRings.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID);
        +                projectionMap.put(KeyRings.KEY_ID, Keys.KEY_ID);
        +                projectionMap.put(KeyRings.KEY_SIZE, Keys.KEY_SIZE);
        +                projectionMap.put(KeyRings.IS_REVOKED, Keys.IS_REVOKED);
        +                projectionMap.put(KeyRings.CAN_CERTIFY, Keys.CAN_CERTIFY);
        +                projectionMap.put(KeyRings.CAN_ENCRYPT, Keys.CAN_ENCRYPT);
        +                projectionMap.put(KeyRings.CAN_SIGN, Keys.CAN_SIGN);
        +                projectionMap.put(KeyRings.CREATION, Keys.CREATION);
        +                projectionMap.put(KeyRings.EXPIRY, Keys.EXPIRY);
        +                projectionMap.put(KeyRings.ALGORITHM, Keys.ALGORITHM);
        +                projectionMap.put(KeyRings.FINGERPRINT, Keys.FINGERPRINT);
        +                projectionMap.put(KeyRings.USER_ID, UserIds.USER_ID);
        +                projectionMap.put(KeyRings.HAS_SECRET, "(" + Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + " IS NOT NULL) AS " + KeyRings.HAS_SECRET);
                         qb.setProjectionMap(projectionMap);
         
                         qb.setTables(
                             Tables.KEYS
                                 + " INNER JOIN " + Tables.USER_IDS + " ON ("
        -                                    + Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID
        +                                    + Tables.KEYS + "." + Keys.MASTER_KEY_ID
                                         + " = "
        -                                    + Tables.USER_IDS + "." + UserIdsColumns.MASTER_KEY_ID
        -                            + " AND " + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = 0"
        +                                    + Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID
        +                            + " AND " + Tables.USER_IDS + "." + UserIds.RANK + " = 0"
                                 + ") LEFT JOIN " + Tables.KEY_RINGS_SECRET + " ON ("
        -                            + Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID
        +                            + Tables.KEYS + "." + Keys.MASTER_KEY_ID
                                         + " = "
        -                            + Tables.KEY_RINGS_SECRET + "." + KeyRingsColumns.MASTER_KEY_ID
        +                            + Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID
                                 + ")"
                             );
        -                qb.appendWhere(Tables.KEYS + "." + KeysColumns.RANK + " = 0");
        +                qb.appendWhere(Tables.KEYS + "." + Keys.RANK + " = 0");
         
                         if(match == KEY_RING_UNIFIED) {
        -                    qb.appendWhere(" AND " + Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID + " = ");
        +                    qb.appendWhere(" AND " + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " = ");
                             qb.appendWhereEscapeString(uri.getPathSegments().get(1));
                         } else if (TextUtils.isEmpty(sortOrder)) {
                             sortOrder =
                                     Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + " IS NULL DESC"
        -                            + Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
        +                            + Tables.USER_IDS + "." + UserIds.USER_ID + " ASC";
                         }
         
                         // uri to watch is all /key_rings/
        @@ -276,38 +271,38 @@ public class KeychainProvider extends ContentProvider {
                             if (i != 0) {
                                 emailWhere += " OR ";
                             }
        -                    emailWhere += "tmp." + UserIdsColumns.USER_ID + " LIKE ";
        +                    emailWhere += "tmp." + UserIds.USER_ID + " LIKE ";
                             // match '*', so it has to be at the *end* of the user id
                             emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">");
                             gotCondition = true;
                         }
         
                         if (gotCondition) {
        -                    qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM "
        -                            + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID
        -                            + " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + emailWhere
        +                    qb.appendWhere(" AND EXISTS (SELECT tmp." + Base._ID + " FROM "
        +                            + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIds.KEY_RING_ROW_ID
        +                            + " = " + Tables.KEY_RINGS + "." + Base._ID + " AND (" + emailWhere
                                     + "))");
                         }*/
         
                     case KEY_RING_KEYS: {
                         HashMap projectionMap = new HashMap();
        -                projectionMap.put(BaseColumns._ID, Tables.KEYS + ".oid AS _id");
        -                projectionMap.put(KeysColumns.MASTER_KEY_ID, Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID);
        -                projectionMap.put(KeysColumns.RANK, Tables.KEYS + "." + KeysColumns.RANK);
        -                projectionMap.put(KeysColumns.KEY_ID, KeysColumns.KEY_ID);
        -                projectionMap.put(KeysColumns.KEY_SIZE, KeysColumns.KEY_SIZE);
        -                projectionMap.put(KeysColumns.IS_REVOKED, KeysColumns.IS_REVOKED);
        -                projectionMap.put(KeysColumns.CAN_CERTIFY, KeysColumns.CAN_CERTIFY);
        -                projectionMap.put(KeysColumns.CAN_ENCRYPT, KeysColumns.CAN_ENCRYPT);
        -                projectionMap.put(KeysColumns.CAN_SIGN, KeysColumns.CAN_SIGN);
        -                projectionMap.put(KeysColumns.CREATION, KeysColumns.CREATION);
        -                projectionMap.put(KeysColumns.EXPIRY, KeysColumns.EXPIRY);
        -                projectionMap.put(KeysColumns.ALGORITHM, KeysColumns.ALGORITHM);
        -                projectionMap.put(KeysColumns.FINGERPRINT, KeysColumns.FINGERPRINT);
        +                projectionMap.put(Keys._ID, Tables.KEYS + ".oid AS _id");
        +                projectionMap.put(Keys.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID);
        +                projectionMap.put(Keys.RANK, Tables.KEYS + "." + Keys.RANK);
        +                projectionMap.put(Keys.KEY_ID, Keys.KEY_ID);
        +                projectionMap.put(Keys.KEY_SIZE, Keys.KEY_SIZE);
        +                projectionMap.put(Keys.IS_REVOKED, Keys.IS_REVOKED);
        +                projectionMap.put(Keys.CAN_CERTIFY, Keys.CAN_CERTIFY);
        +                projectionMap.put(Keys.CAN_ENCRYPT, Keys.CAN_ENCRYPT);
        +                projectionMap.put(Keys.CAN_SIGN, Keys.CAN_SIGN);
        +                projectionMap.put(Keys.CREATION, Keys.CREATION);
        +                projectionMap.put(Keys.EXPIRY, Keys.EXPIRY);
        +                projectionMap.put(Keys.ALGORITHM, Keys.ALGORITHM);
        +                projectionMap.put(Keys.FINGERPRINT, Keys.FINGERPRINT);
                         qb.setProjectionMap(projectionMap);
         
                         qb.setTables(Tables.KEYS);
        -                qb.appendWhere(KeysColumns.MASTER_KEY_ID + " = ");
        +                qb.appendWhere(Keys.MASTER_KEY_ID + " = ");
                         qb.appendWhereEscapeString(uri.getPathSegments().get(1));
         
                         break;
        @@ -315,7 +310,7 @@ public class KeychainProvider extends ContentProvider {
         
                     case KEY_RING_USER_IDS: {
                         HashMap projectionMap = new HashMap();
        -                projectionMap.put(BaseColumns._ID, Tables.USER_IDS + ".oid AS _id");
        +                projectionMap.put(UserIds._ID, Tables.USER_IDS + ".oid AS _id");
                         projectionMap.put(UserIds.MASTER_KEY_ID, UserIds.MASTER_KEY_ID);
                         projectionMap.put(UserIds.USER_ID, UserIds.USER_ID);
                         projectionMap.put(UserIds.RANK, UserIds.RANK);
        @@ -323,36 +318,44 @@ public class KeychainProvider extends ContentProvider {
                         qb.setProjectionMap(projectionMap);
         
                         qb.setTables(Tables.USER_IDS);
        -                qb.appendWhere(UserIdsColumns.MASTER_KEY_ID + " = ");
        +                qb.appendWhere(UserIds.MASTER_KEY_ID + " = ");
                         qb.appendWhereEscapeString(uri.getPathSegments().get(1));
         
        +                if (TextUtils.isEmpty(sortOrder)) {
        +                    sortOrder = UserIds.RANK + " ASC";
        +                }
        +
                         break;
         
                     }
         
        +            case KEY_RINGS_PUBLIC:
                     case KEY_RING_PUBLIC: {
                         HashMap projectionMap = new HashMap();
        -                projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS_PUBLIC + ".oid AS _id");
        -                projectionMap.put(KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID);
        -                projectionMap.put(KeyRings.KEY_RING_DATA, KeyRings.KEY_RING_DATA);
        +                projectionMap.put(KeyRingData._ID, Tables.KEY_RINGS_PUBLIC + ".oid AS _id");
        +                projectionMap.put(KeyRingData.MASTER_KEY_ID, KeyRingData.MASTER_KEY_ID);
        +                projectionMap.put(KeyRingData.KEY_RING_DATA, KeyRingData.KEY_RING_DATA);
                         qb.setProjectionMap(projectionMap);
         
                         qb.setTables(Tables.KEY_RINGS_PUBLIC);
        -                qb.appendWhere(KeyRingsColumns.MASTER_KEY_ID + " = ");
        -                qb.appendWhereEscapeString(uri.getPathSegments().get(1));
        +
        +                if(match == KEY_RING_PUBLIC) {
        +                    qb.appendWhere(KeyRings.MASTER_KEY_ID + " = ");
        +                    qb.appendWhereEscapeString(uri.getPathSegments().get(1));
        +                }
         
                         break;
                     }
         
                     case KEY_RING_SECRET: {
                         HashMap projectionMap = new HashMap();
        -                projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS_SECRET + ".oid AS _id");
        -                projectionMap.put(KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID);
        -                projectionMap.put(KeyRings.KEY_RING_DATA, KeyRings.KEY_RING_DATA);
        +                projectionMap.put(KeyRingData._ID, Tables.KEY_RINGS_SECRET + ".oid AS _id");
        +                projectionMap.put(KeyRingData.MASTER_KEY_ID, KeyRingData.MASTER_KEY_ID);
        +                projectionMap.put(KeyRingData.KEY_RING_DATA, KeyRingData.KEY_RING_DATA);
                         qb.setProjectionMap(projectionMap);
         
                         qb.setTables(Tables.KEY_RINGS_SECRET);
        -                qb.appendWhere(KeyRingsColumns.MASTER_KEY_ID + " = ");
        +                qb.appendWhere(KeyRings.MASTER_KEY_ID + " = ");
                         qb.appendWhereEscapeString(uri.getPathSegments().get(1));
         
                         break;
        @@ -429,23 +432,23 @@ public class KeychainProvider extends ContentProvider {
                     switch (match) {
                         case KEY_RING_PUBLIC:
                             db.insertOrThrow(Tables.KEY_RINGS_PUBLIC, null, values);
        -                    keyId = values.getAsLong(KeyRingsColumns.MASTER_KEY_ID);
        +                    keyId = values.getAsLong(KeyRings.MASTER_KEY_ID);
                             break;
         
                         case KEY_RING_SECRET:
                             db.insertOrThrow(Tables.KEY_RINGS_SECRET, null, values);
        -                    keyId = values.getAsLong(KeyRingsColumns.MASTER_KEY_ID);
        +                    keyId = values.getAsLong(KeyRings.MASTER_KEY_ID);
                             break;
         
                         case KEY_RING_KEYS:
                             Log.d(Constants.TAG, "keys");
                             db.insertOrThrow(Tables.KEYS, null, values);
        -                    keyId = values.getAsLong(KeysColumns.MASTER_KEY_ID);
        +                    keyId = values.getAsLong(Keys.MASTER_KEY_ID);
                             break;
         
                         case KEY_RING_USER_IDS:
                             db.insertOrThrow(Tables.USER_IDS, null, values);
        -                    keyId = values.getAsLong(UserIdsColumns.MASTER_KEY_ID);
        +                    keyId = values.getAsLong(UserIds.MASTER_KEY_ID);
                             break;
         
                         case API_APPS:
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
        index 18eaa375a..339e6a069 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
        @@ -43,6 +43,7 @@ import org.sufficientlysecure.keychain.pgp.PgpHelper;
         import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
         import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
         import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
         import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
         import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
         import org.sufficientlysecure.keychain.remote.AccountSettings;
        @@ -65,11 +66,11 @@ public class ProviderHelper {
              */
             public static PGPKeyRing getPGPKeyRing(Context context, Uri queryUri) {
                 Cursor cursor = context.getContentResolver().query(queryUri,
        -                new String[]{KeyRings._ID, KeyRings.KEY_RING_DATA}, null, null, null);
        +                new String[]{KeyRings._ID, KeyRingData.KEY_RING_DATA}, null, null, null);
         
                 PGPKeyRing keyRing = null;
                 if (cursor != null && cursor.moveToFirst()) {
        -            int keyRingDataCol = cursor.getColumnIndex(KeyRings.KEY_RING_DATA);
        +            int keyRingDataCol = cursor.getColumnIndex(KeyRingData.KEY_RING_DATA);
         
                     byte[] data = cursor.getBlob(keyRingDataCol);
                     if (data != null) {
        @@ -156,7 +157,7 @@ public class ProviderHelper {
              */
             public static PGPPublicKeyRing getPGPPublicKeyRing(Context context,
                                                                             long masterKeyId) {
        -        Uri queryUri = KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId));
        +        Uri queryUri = KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId));
                 return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri);
             }
         
        @@ -165,7 +166,7 @@ public class ProviderHelper {
              */
             public static PGPSecretKeyRing getPGPSecretKeyRing(Context context,
                                                                             long masterKeyId) {
        -        Uri queryUri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId));
        +        Uri queryUri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId));
                 return (PGPSecretKeyRing) getPGPKeyRing(context, queryUri);
             }
         
        @@ -178,12 +179,11 @@ public class ProviderHelper {
                 long masterKeyId = masterKey.getKeyID();
         
                 // IF there is a secret key, preserve it!
        -        // TODO This even necessary?
        -        // PGPSecretKeyRing secretRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId);
        +        PGPSecretKeyRing secretRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId);
         
                 // delete old version of this keyRing, which also deletes all keys and userIds on cascade
                 try {
        -            context.getContentResolver().delete(KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null);
        +            context.getContentResolver().delete(KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null);
                 } catch (UnsupportedOperationException e) {
                     Log.e(Constants.TAG, "Key could not be deleted! Maybe we are creating a new one!", e);
                 }
        @@ -193,11 +193,11 @@ public class ProviderHelper {
                 // NOTE: If we would not use the same _ID again,
                 // getting back to the ViewKeyActivity would result in Nullpointer,
                 // because the currently loaded key would be gone from the database
        -        values.put(KeyRings.MASTER_KEY_ID, masterKeyId);
        -        values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded());
        +        values.put(KeyRingData.MASTER_KEY_ID, masterKeyId);
        +        values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded());
         
                 // insert new version of this keyRing
        -        Uri uri = KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId));
        +        Uri uri = KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId));
                 Uri insertedUri = context.getContentResolver().insert(uri, values);
         
                 // save all keys and userIds included in keyRing object in database
        @@ -233,31 +233,43 @@ public class ProviderHelper {
                 }
         
                 // Save the saved keyring (if any)
        -        // TODO this even necessary? see above...
        -        // if(secretRing != null)
        -            // saveKeyRing(context, secretRing);
        +        if(secretRing != null) {
        +            saveKeyRing(context, secretRing);
        +        }
         
             }
         
             /**
        -     * Saves PGPSecretKeyRing with its keys and userIds in DB
        +     * Saves a PGPSecretKeyRing in the DB. This will only work if a corresponding public keyring
        +     * is already in the database!
              */
             @SuppressWarnings("unchecked")
             public static void saveKeyRing(Context context, PGPSecretKeyRing keyRing) throws IOException {
        -        PGPSecretKey masterKey = keyRing.getSecretKey();
        -        long masterKeyId = masterKey.getKeyID();
        +        long masterKeyId = keyRing.getPublicKey().getKeyID();
         
        -        // TODO Make sure there is a public key for this secret key in the db (create one maybe)
        +        // save secret keyring
        +        ContentValues values = new ContentValues();
        +        values.put(KeyRingData.MASTER_KEY_ID, masterKeyId);
        +        values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded());
        +        // insert new version of this keyRing
        +        Uri uri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId));
        +        context.getContentResolver().insert(uri, values);
         
        -        {
        -            ContentValues values = new ContentValues();
        -            values.put(KeyRings.MASTER_KEY_ID, masterKeyId);
        -            values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded());
        -            // insert new version of this keyRing
        -            Uri uri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId));
        -            context.getContentResolver().insert(uri, values);
        -        }
        +    }
         
        +    /**
        +     * Saves (or updates) a pair of public and secret KeyRings in the database
        +     */
        +    @SuppressWarnings("unchecked")
        +    public static void saveKeyRing(Context context, PGPPublicKeyRing pubRing, PGPSecretKeyRing privRing) throws IOException {
        +        long masterKeyId = pubRing.getPublicKey().getKeyID();
        +
        +        // delete secret keyring (so it isn't unnecessarily saved by public-saveKeyRing below)
        +        context.getContentResolver().delete(KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId)), null, null);
        +
        +        // save public keyring
        +        saveKeyRing(context, pubRing);
        +        saveKeyRing(context, privRing);
             }
         
             /**
        @@ -314,24 +326,14 @@ public class ProviderHelper {
                 return ContentProviderOperation.newInsert(uri).withValues(values).build();
             }
         
        -    public static void deletePublicKeyRing(Context context, long masterKeyId) {
        -        ContentResolver cr = context.getContentResolver();
        -        cr.delete(KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null);
        -    }
        -
        -    public static void deleteSecretKeyRing(Context context, long masterKeyId) {
        -        ContentResolver cr = context.getContentResolver();
        -        cr.delete(KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId)), null, null);
        -    }
        -
             public static boolean hasSecretKeyByMasterKeyId(Context context, long masterKeyId) {
        -        Uri queryUri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId));
        +        Uri queryUri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId));
                 // see if we can get our master key id back from the uri
                 return getMasterKeyId(context, queryUri) == masterKeyId;
             }
         
        -    /**
        -     * Get master key id of key
        +    /** Find the master key id related to a given query. The id will either be extracted from the
        +     * query, which should work for all specific /key_rings/ queries, or will be queried if it can't.
              */
             public static long getMasterKeyId(Context context, Uri queryUri) {
                 // try extracting from the uri first
        @@ -339,39 +341,25 @@ public class ProviderHelper {
                     return Long.parseLong(queryUri.getPathSegments().get(1));
                 } catch(NumberFormatException e) {
                     // didn't work? oh well.
        +            Log.d(Constants.TAG, "Couldn't get masterKeyId from URI, querying...");
                 }
        -
        -        Cursor cursor = context.getContentResolver().query(queryUri, new String[] {
        -                KeyRings.MASTER_KEY_ID
        -        }, null, null, null);
        -
        -        long masterKeyId = 0;
        -        try {
        -            if (cursor != null && cursor.moveToFirst()) {
        -                int masterKeyIdCol = cursor.getColumnIndexOrThrow(KeyRings.MASTER_KEY_ID);
        -
        -                masterKeyId = cursor.getLong(masterKeyIdCol);
        -            }
        -        } finally {
        -            if (cursor != null) {
        -                cursor.close();
        -            }
        -        }
        -
        -        return masterKeyId;
        +        Object data = getUnifiedData(context, queryUri, KeyRings.MASTER_KEY_ID);
        +        if(data instanceof Long)
        +            return (Long) data;
        +        // TODO better error handling?
        +        return 0L;
             }
         
        -    public static ArrayList getKeyRingsAsArmoredString(Context context, Uri uri,
        -                                                               long[] masterKeyIds) {
        +    public static ArrayList getKeyRingsAsArmoredString(Context context, long[] masterKeyIds) {
                 ArrayList output = new ArrayList();
         
                 if (masterKeyIds != null && masterKeyIds.length > 0) {
         
        -            Cursor cursor = getCursorWithSelectedKeyringMasterKeyIds(context, uri, masterKeyIds);
        +            Cursor cursor = getCursorWithSelectedKeyringMasterKeyIds(context, masterKeyIds);
         
                     if (cursor != null) {
        -                int masterIdCol = cursor.getColumnIndex(KeyRings.MASTER_KEY_ID);
        -                int dataCol = cursor.getColumnIndex(KeyRings.KEY_RING_DATA);
        +                int masterIdCol = cursor.getColumnIndex(KeyRingData.MASTER_KEY_ID);
        +                int dataCol = cursor.getColumnIndex(KeyRingData.KEY_RING_DATA);
                         if (cursor.moveToFirst()) {
                             do {
                                 Log.d(Constants.TAG, "masterKeyId: " + cursor.getLong(masterIdCol));
        @@ -421,48 +409,11 @@ public class ProviderHelper {
                     return null;
                 }
             }
        -
        -    public static byte[] getKeyRingsAsByteArray(Context context, Uri uri, long[] masterKeyIds) {
        -        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        -
        -        if (masterKeyIds != null && masterKeyIds.length > 0) {
        -
        -            Cursor cursor = getCursorWithSelectedKeyringMasterKeyIds(context, uri, masterKeyIds);
        -
        -            if (cursor != null) {
        -                int masterIdCol = cursor.getColumnIndex(KeyRings.MASTER_KEY_ID);
        -                int dataCol = cursor.getColumnIndex(KeyRings.KEY_RING_DATA);
        -                if (cursor.moveToFirst()) {
        -                    do {
        -                        Log.d(Constants.TAG, "masterKeyId: " + cursor.getLong(masterIdCol));
        -
        -                        // get actual keyring data blob and write it to ByteArrayOutputStream
        -                        try {
        -                            bos.write(cursor.getBlob(dataCol));
        -                        } catch (IOException e) {
        -                            Log.e(Constants.TAG, "IOException", e);
        -                        }
        -                    } while (cursor.moveToNext());
        -                }
        -            }
        -
        -            if (cursor != null) {
        -                cursor.close();
        -            }
        -
        -        } else {
        -            Log.e(Constants.TAG, "No master keys given!");
        -        }
        -
        -        return bos.toByteArray();
        -    }
        -
        -    private static Cursor getCursorWithSelectedKeyringMasterKeyIds(Context context, Uri baseUri,
        -                                                                   long[] masterKeyIds) {
        +    private static Cursor getCursorWithSelectedKeyringMasterKeyIds(Context context, long[] masterKeyIds) {
                 Cursor cursor = null;
                 if (masterKeyIds != null && masterKeyIds.length > 0) {
         
        -            String inMasterKeyList = KeyRings.MASTER_KEY_ID + " IN (";
        +            String inMasterKeyList = KeyRingData.MASTER_KEY_ID + " IN (";
                     for (int i = 0; i < masterKeyIds.length; ++i) {
                         if (i != 0) {
                             inMasterKeyList += ", ";
        @@ -471,9 +422,9 @@ public class ProviderHelper {
                     }
                     inMasterKeyList += ")";
         
        -            cursor = context.getContentResolver().query(baseUri,
        -                    new String[]{KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.KEY_RING_DATA},
        -                    inMasterKeyList, null, null);
        +            cursor = context.getContentResolver().query(KeyRingData.buildPublicKeyRingUri(), new String[] {
        +                    KeyRingData._ID, KeyRingData.MASTER_KEY_ID, KeyRingData.KEY_RING_DATA
        +                }, inMasterKeyList, null, null);
                 }
         
                 return cursor;
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
        index f9e143d87..6ee209c5c 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
        @@ -518,8 +518,8 @@ public class KeychainIntentService extends IntentService
                             PgpKeyOperation.Pair pair =
                                 keyOperations.buildSecretKey(privkey, pubkey, saveParams);
                             setProgress(R.string.progress_saving_key_ring, 90, 100);
        -                    ProviderHelper.saveKeyRing(this, pair.first);
        -                    ProviderHelper.saveKeyRing(this, pair.second);
        +                    // save the pair
        +                    ProviderHelper.saveKeyRing(this, pair.second, pair.first);
                             setProgress(R.string.progress_done, 100, 100);
                         }
                         PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassphrase);
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
        index 0caf60aa1..e6fd59d55 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
        @@ -57,6 +57,7 @@ import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
         import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
         import org.sufficientlysecure.keychain.provider.KeychainContract;
         import org.sufficientlysecure.keychain.provider.ProviderHelper;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
         import org.sufficientlysecure.keychain.service.KeychainIntentService;
         import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
         import org.sufficientlysecure.keychain.service.PassphraseCacheService;
        @@ -345,7 +346,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
                         }
                         return true;
                     case R.id.menu_key_edit_delete:
        -                Uri convertUri = KeychainContract.KeyRings.buildSecretKeyRingUri(mDataUri);
        +                Uri convertUri = KeyRingData.buildSecretKeyRingUri(mDataUri);
                             // Message is received after key is deleted
                             Handler returnHandler = new Handler() {
                                 @Override
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
        index cc0abe48a..ecd742896 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
        @@ -58,12 +58,9 @@ import org.sufficientlysecure.keychain.Id;
         import org.sufficientlysecure.keychain.R;
         import org.sufficientlysecure.keychain.helper.ExportHelper;
         import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
        -import org.sufficientlysecure.keychain.provider.KeychainContract;
         import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
        -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyTypes;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
         import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
        -import org.sufficientlysecure.keychain.provider.KeychainDatabase;
        -import org.sufficientlysecure.keychain.provider.ProviderHelper;
         import org.sufficientlysecure.keychain.ui.adapter.HighlightQueryCursorAdapter;
         import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
         import org.sufficientlysecure.keychain.util.Log;
        @@ -257,11 +254,11 @@ public class KeyListFragment extends Fragment
         
             // These are the rows that we will retrieve.
             static final String[] PROJECTION = new String[]{
        -            KeychainContract.KeyRings._ID,
        -            KeychainContract.Keys.MASTER_KEY_ID,
        -            KeychainContract.UserIds.USER_ID,
        -            KeychainContract.Keys.IS_REVOKED,
        -            KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID
        +            KeyRings._ID,
        +            KeyRings.MASTER_KEY_ID,
        +            KeyRings.USER_ID,
        +            KeyRings.IS_REVOKED,
        +            KeyRings.HAS_SECRET
             };
         
             static final int INDEX_MASTER_KEY_ID = 1;
        @@ -269,11 +266,8 @@ public class KeyListFragment extends Fragment
             static final int INDEX_IS_REVOKED = 3;
             static final int INDEX_HAS_SECRET = 4;
         
        -    static final String SORT_ORDER =
        -            // show secret before public key
        -            KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID + " IS NULL ASC, " +
        -                    // sort by user id otherwise
        -                    UserIds.USER_ID + " ASC";
        +    // show secret before public key, sort by user id otherwise
        +    static final String SORT_ORDER = KeyRings.HAS_SECRET + " DESC, " + UserIds.USER_ID + " ASC";
         
             @Override
             public Loader onCreateLoader(int id, Bundle args) {
        @@ -283,7 +277,7 @@ public class KeyListFragment extends Fragment
                 String where = null;
                 String whereArgs[] = null;
                 if (mCurQuery != null) {
        -            where = KeychainContract.UserIds.USER_ID + " LIKE ?";
        +            where = KeyRings.USER_ID + " LIKE ?";
                     whereArgs = new String[]{"%" + mCurQuery + "%"};
                 }
                 // Now create and return a CursorLoader that will take care of
        @@ -329,17 +323,15 @@ public class KeyListFragment extends Fragment
                     viewIntent = new Intent(getActivity(), ViewKeyActivityJB.class);
                 }
                 viewIntent.setData(
        -                KeychainContract
        -                        .KeyRings.buildGenericKeyRingUri(
        -                                            Long.toString(mAdapter.getMasterKeyId(position))));
        +                KeyRings.buildGenericKeyRingUri(Long.toString(mAdapter.getMasterKeyId(position))));
                 startActivity(viewIntent);
             }
         
             @TargetApi(11)
        -    protected void encrypt(ActionMode mode, long[] keyRingMasterKeyIds) {
        +    protected void encrypt(ActionMode mode, long[] masterKeyIds) {
                 Intent intent = new Intent(getActivity(), EncryptActivity.class);
                 intent.setAction(EncryptActivity.ACTION_ENCRYPT);
        -        intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, keyRingMasterKeyIds);
        +        intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, masterKeyIds);
                 // used instead of startActivity set actionbar based on callingPackage
                 startActivityForResult(intent, 0);
         
        @@ -507,7 +499,7 @@ public class KeyListFragment extends Fragment
                         Button button = (Button) view.findViewById(R.id.edit);
                         TextView revoked = (TextView) view.findViewById(R.id.revoked);
         
        -                if (!cursor.isNull(KeyListFragment.INDEX_HAS_SECRET)) {
        +                if (cursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) {
                             // this is a secret key - show the edit button
                             statusDivider.setVisibility(View.VISIBLE);
                             statusLayout.setVisibility(View.VISIBLE);
        @@ -518,9 +510,7 @@ public class KeyListFragment extends Fragment
                             button.setOnClickListener(new OnClickListener() {
                                 public void onClick(View view) {
                                     Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
        -                            editIntent.setData(
        -                                    KeychainContract.KeyRings
        -                                            .buildSecretKeyRingUri(Long.toString(id)));
        +                            editIntent.setData(KeyRingData.buildSecretKeyRingUri(Long.toString(id)));
                                     editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
                                     startActivityForResult(editIntent, 0);
                                 }
        @@ -581,7 +571,7 @@ public class KeyListFragment extends Fragment
                         throw new IllegalStateException("couldn't move cursor to position " + position);
                     }
         
        -            if (!mCursor.isNull(KeyListFragment.INDEX_HAS_SECRET)) {
        +            if (mCursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) {
                         { // set contact count
                             int num = mCursor.getCount();
                             String contactsTotal = getResources().getQuantityString(R.plurals.n_contacts, num, num);
        @@ -621,7 +611,7 @@ public class KeyListFragment extends Fragment
                     }
         
                     // early breakout: all secret keys are assigned id 0
        -            if (!mCursor.isNull(KeyListFragment.INDEX_HAS_SECRET)) {
        +            if (mCursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) {
                         return 1L;
                     }
                     // otherwise, return the first character of the name as ID
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        index 2437270e5..b60e75fa9 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        @@ -185,8 +185,8 @@ public class ViewKeyActivity extends ActionBarActivity {
                 } else {
                     // get public keyring as ascii armored string
                     long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
        -            ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this,
        -                    dataUri, new long[]{masterKeyId});
        +            ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(
        +                    this, new long[]{ masterKeyId });
         
                     content = keyringArmored.get(0);
         
        @@ -216,8 +216,8 @@ public class ViewKeyActivity extends ActionBarActivity {
             private void copyToClipboard(Uri dataUri) {
                 // get public keyring as ascii armored string
                 long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
        -        ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this, dataUri,
        -                new long[]{masterKeyId});
        +        ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(
        +                this, new long[]{ masterKeyId });
         
                 ClipboardReflection.copyToClipboard(this, keyringArmored.get(0));
                 Toast.makeText(getApplicationContext(), R.string.key_copied_to_clipboard, Toast.LENGTH_LONG)
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        index 75853ac2a..616200800 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        @@ -38,7 +38,10 @@ import com.beardedhen.androidbootstrap.BootstrapButton;
         import org.sufficientlysecure.keychain.Constants;
         import org.sufficientlysecure.keychain.R;
         import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
        -import org.sufficientlysecure.keychain.provider.KeychainContract;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
         import org.sufficientlysecure.keychain.provider.ProviderHelper;
         import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter;
         import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter;
        @@ -124,6 +127,7 @@ public class ViewKeyMainFragment extends Fragment implements
         
                 { // label whether secret key is available, and edit button if it is
                     final long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), mDataUri);
        +            // TODO do this some other way...
                     if (ProviderHelper.hasSecretKeyByMasterKeyId(getActivity(), masterKeyId)) {
                         // set this attribute. this is a LITTLE unclean, but we have the info available
                         // right here, so why not.
        @@ -141,8 +145,7 @@ public class ViewKeyMainFragment extends Fragment implements
                             public void onClick(View view) {
                                 Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
                                 editIntent.setData(
        -                                KeychainContract
        -                                        .KeyRings.buildSecretKeyRingUri(
        +                                KeyRingData.buildSecretKeyRingUri(
                                                 Long.toString(masterKeyId)));
                                 editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
                                 startActivityForResult(editIntent, 0);
        @@ -161,7 +164,7 @@ public class ViewKeyMainFragment extends Fragment implements
                     // TODO see todo note above, doing this here for now
                     mActionCertify.setOnClickListener(new View.OnClickListener() {
                         public void onClick(View view) {
        -                    certifyKey(KeychainContract.KeyRings.buildGenericKeyRingUri(
        +                    certifyKey(KeyRings.buildGenericKeyRingUri(
                                     Long.toString(masterKeyId)
                             ));
                         }
        @@ -190,31 +193,26 @@ public class ViewKeyMainFragment extends Fragment implements
             }
         
             static final String[] USER_IDS_PROJECTION =
        -            new String[]{
        -                    KeychainContract.UserIds._ID,
        -                    KeychainContract.UserIds.USER_ID,
        -                    KeychainContract.UserIds.RANK,
        +            new String[] {
        +                    UserIds._ID,
        +                    UserIds.USER_ID,
        +                    UserIds.RANK,
                     };
             static final int INDEX_UID_UID = 1;
        -    static final String USER_IDS_SORT_ORDER =
        -            KeychainContract.UserIds.RANK + " COLLATE LOCALIZED ASC";
        -
        -    static final String[] KEYS_PROJECTION =
        -            new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID,
        -                    KeychainContract.Keys.ALGORITHM, KeychainContract.Keys.RANK,
        -                    KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY,
        -                    KeychainContract.Keys.CAN_SIGN, KeychainContract.Keys.CAN_ENCRYPT,
        -                    KeychainContract.Keys.IS_REVOKED, KeychainContract.Keys.CREATION,
        -                    KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT};
        -    static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC";
        +
        +    static final String[] KEYS_PROJECTION = new String[] {
        +            Keys._ID,
        +            Keys.KEY_ID, Keys.RANK,
        +            Keys.ALGORITHM, Keys.KEY_SIZE,
        +            Keys.CAN_CERTIFY, Keys.CAN_ENCRYPT,
        +            Keys.CAN_SIGN, Keys.IS_REVOKED,
        +            Keys.CREATION, Keys.EXPIRY,
        +            Keys.FINGERPRINT
        +    };
             static final int KEYS_INDEX_KEY_ID = 1;
        -    static final int KEYS_INDEX_ALGORITHM = 2;
        -    static final int KEYS_INDEX_RANK = 3;
        +    static final int KEYS_INDEX_ALGORITHM = 3;
             static final int KEYS_INDEX_KEY_SIZE = 4;
        -    static final int KEYS_INDEX_CAN_CERTIFY = 5;
        -    static final int KEYS_INDEX_CAN_SIGN = 6;
        -    static final int KEYS_INDEX_CAN_ENCRYPT = 7;
        -    static final int KEYS_INDEX_IS_REVOKED = 8;
        +    static final int KEYS_INDEX_CAN_ENCRYPT = 6;
             static final int KEYS_INDEX_CREATION = 9;
             static final int KEYS_INDEX_EXPIRY = 10;
             static final int KEYS_INDEX_FINGERPRINT = 11;
        @@ -222,19 +220,18 @@ public class ViewKeyMainFragment extends Fragment implements
             public Loader onCreateLoader(int id, Bundle args) {
                 switch (id) {
                     case LOADER_ID_USER_IDS: {
        -                Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri);
        +                Uri baseUri = UserIds.buildUserIdsUri(mDataUri);
         
                         // Now create and return a CursorLoader that will take care of
                         // creating a Cursor for the data being displayed.
        -                return new CursorLoader(getActivity(), baseUri, USER_IDS_PROJECTION, null, null,
        -                        USER_IDS_SORT_ORDER);
        +                return new CursorLoader(getActivity(), baseUri, USER_IDS_PROJECTION, null, null, null);
                     }
                     case LOADER_ID_KEYS: {
        -                Uri baseUri = KeychainContract.Keys.buildKeysUri(mDataUri);
        +                Uri baseUri = Keys.buildKeysUri(mDataUri);
         
                         // Now create and return a CursorLoader that will take care of
                         // creating a Cursor for the data being displayed.
        -                return new CursorLoader(getActivity(), baseUri, KEYS_PROJECTION, null, null, KEYS_SORT_ORDER);
        +                return new CursorLoader(getActivity(), baseUri, KEYS_PROJECTION, null, null, null);
                     }
         
                     default:
        @@ -343,7 +340,7 @@ public class ViewKeyMainFragment extends Fragment implements
         
             private void encryptToContact(Uri dataUri) {
                 // TODO preselect from uri? should be feasible without trivial query
        -        long keyId = Long.parseLong(dataUri.getPathSegments().get(1));
        +        long keyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
         
                 long[] encryptionKeyIds = new long[]{ keyId };
                 Intent intent = new Intent(getActivity(), EncryptActivity.class);
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
        index 57dbb7794..feaa0b4cd 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
        @@ -20,8 +20,6 @@ package org.sufficientlysecure.keychain.ui.dialog;
         import android.app.AlertDialog;
         import android.app.Dialog;
         import android.content.DialogInterface;
        -import android.database.Cursor;
        -import android.net.Uri;
         import android.os.Bundle;
         import android.os.Message;
         import android.os.Messenger;
        @@ -35,14 +33,13 @@ import android.widget.LinearLayout;
         import android.widget.TextView;
         
         import org.sufficientlysecure.keychain.Constants;
        -import org.sufficientlysecure.keychain.Id;
         import org.sufficientlysecure.keychain.R;
        -import org.sufficientlysecure.keychain.provider.KeychainContract;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
         import org.sufficientlysecure.keychain.provider.KeychainDatabase;
         import org.sufficientlysecure.keychain.provider.ProviderHelper;
         import org.sufficientlysecure.keychain.util.Log;
         
        -import java.util.ArrayList;
         import java.util.HashMap;
         
         public class DeleteKeyDialogFragment extends DialogFragment {
        @@ -107,13 +104,11 @@ public class DeleteKeyDialogFragment extends DialogFragment {
                     long masterKeyId = masterKeyIds[0];
         
                     HashMap data = ProviderHelper.getUnifiedData(activity, masterKeyId, new String[]{
        -                    KeychainContract.UserIds.USER_ID,
        -                    KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID
        +                    KeyRings.USER_ID,
        +                    KeyRings.HAS_SECRET
                     });
        -            String userId = (String) data.get(KeychainContract.UserIds.USER_ID);
        -            boolean hasSecret = data.get(
        -                    KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID
        -            ) instanceof Long;
        +            String userId = (String) data.get(KeyRings.USER_ID);
        +            boolean hasSecret = ((Long) data.get(KeyRings.HAS_SECRET)) == 1;
         
                     // Hide the Checkbox and TextView since this is a single selection,user will be notified through message
                     mDeleteSecretKeyView.setVisibility(View.GONE);
        @@ -136,7 +131,7 @@ public class DeleteKeyDialogFragment extends DialogFragment {
                         boolean success = false;
                         for(long masterKeyId : masterKeyIds) {
                             int count = activity.getContentResolver().delete(
        -                            KeychainContract.KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null
        +                            KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null
                                 );
                             if(count > 0)
                             success = true;
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
        index 1b81c8b3b..dc9fa6235 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
        @@ -107,7 +107,7 @@ public class ShareQrCodeDialogFragment extends DialogFragment {
                     long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
                     // get public keyring as ascii armored string
                     ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(
        -                    getActivity(), dataUri, new long[] { masterKeyId });
        +                    getActivity(), new long[] { masterKeyId });
         
                     // TODO: binary?
         
        -- 
        cgit v1.2.3
        
        
        From 59f4b4e3e7cc27981e66f140030bef9a3fce3d25 Mon Sep 17 00:00:00 2001
        From: Vincent Breitmoser 
        Date: Fri, 4 Apr 2014 01:04:28 +0200
        Subject: db-overhaul: minor stuff, mostly ProviderHelper
        
        ---
         .../keychain/pgp/PgpDecryptVerify.java             |   6 +-
         .../keychain/provider/ProviderHelper.java          | 119 ++++++++++-----------
         .../keychain/remote/OpenPgpService.java            |   7 +-
         .../keychain/ui/EncryptAsymmetricFragment.java     |   4 +-
         .../keychain/ui/KeyListFragment.java               |   5 +-
         .../keychain/ui/ViewKeyActivity.java               |   4 +-
         .../ui/dialog/PassphraseDialogFragment.java        |   2 +-
         .../ui/dialog/ShareQrCodeDialogFragment.java       |   4 +-
         8 files changed, 73 insertions(+), 78 deletions(-)
        
        (limited to 'OpenPGP-Keychain/src/main/java')
        
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
        index 77edd353c..4b0a07d9b 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
        @@ -232,7 +232,7 @@ public class PgpDecryptVerify {
                         updateProgress(R.string.progress_finding_key, currentProgress, 100);
         
                         PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
        -                secretKey = ProviderHelper.getPGPSecretKeyByKeyId(mContext, encData.getKeyID());
        +                secretKey = ProviderHelper.getPGPSecretKeyRing(mContext, encData.getKeyID()).getSecretKey();
                         if (secretKey != null) {
                             // secret key exists in database
         
        @@ -362,7 +362,7 @@ public class PgpDecryptVerify {
                     for (int i = 0; i < sigList.size(); ++i) {
                         signature = sigList.get(i);
                         signatureKey = ProviderHelper
        -                        .getPGPPublicKeyByKeyId(mContext, signature.getKeyID());
        +                        .getPGPPublicKeyRing(mContext, signature.getKeyID()).getPublicKey();
                         if (signatureKeyId == 0) {
                             signatureKeyId = signature.getKeyID();
                         }
        @@ -546,7 +546,7 @@ public class PgpDecryptVerify {
                 PGPPublicKey signatureKey = null;
                 for (int i = 0; i < sigList.size(); ++i) {
                     signature = sigList.get(i);
        -            signatureKey = ProviderHelper.getPGPPublicKeyByKeyId(mContext, signature.getKeyID());
        +            signatureKey = ProviderHelper.getPGPPublicKeyRing(mContext, signature.getKeyID()).getPublicKey();
                     if (signatureKeyId == 0) {
                         signatureKeyId = signature.getKeyID();
                     }
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
        index 339e6a069..a81368988 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
        @@ -61,44 +61,10 @@ import java.util.Set;
         
         public class ProviderHelper {
         
        -    /**
        -     * Private helper method to get PGPKeyRing from database
        -     */
        -    public static PGPKeyRing getPGPKeyRing(Context context, Uri queryUri) {
        -        Cursor cursor = context.getContentResolver().query(queryUri,
        -                new String[]{KeyRings._ID, KeyRingData.KEY_RING_DATA}, null, null, null);
        -
        -        PGPKeyRing keyRing = null;
        -        if (cursor != null && cursor.moveToFirst()) {
        -            int keyRingDataCol = cursor.getColumnIndex(KeyRingData.KEY_RING_DATA);
        -
        -            byte[] data = cursor.getBlob(keyRingDataCol);
        -            if (data != null) {
        -                keyRing = PgpConversionHelper.BytesToPGPKeyRing(data);
        -            }
        -        }
        -
        -        if (cursor != null) {
        -            cursor.close();
        -        }
        -
        -        return keyRing;
        +    public static Object getGenericData(Context context, Uri uri, String column) {
        +        return getGenericData(context, uri, new String[] { column }).get(column);
             }
        -
        -    public static Object getUnifiedData(Context context, long masterKeyId, String column) {
        -        return getUnifiedData(context, masterKeyId, new String[] { column }).get(column);
        -    }
        -    public static Object getUnifiedData(Context context, Uri uri, String column) {
        -        return getUnifiedData(context, uri, new String[] { column }).get(column);
        -    }
        -
        -    public static HashMap getUnifiedData(Context context, long masterKeyId, String[] proj) {
        -        return getUnifiedData(context, KeyRings.buildGenericKeyRingUri(Long.toString(masterKeyId)), proj);
        -    }
        -
        -    public static HashMap getUnifiedData(Context context, Uri uri, String[] proj) {
        -        uri = KeyRings.buildUnifiedKeyRingUri(uri);
        -
        +    public static HashMap getGenericData(Context context, Uri uri, String[] proj) {
                 Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
         
                 HashMap result = new HashMap(proj.length);
        @@ -135,20 +101,65 @@ public class ProviderHelper {
                 return result;
             }
         
        +    public static Object getUnifiedData(Context context, long masterKeyId, String column) {
        +        return getUnifiedData(context, masterKeyId, new String[] { column }).get(column);
        +    }
        +    public static HashMap getUnifiedData(Context context, long masterKeyId, String[] proj) {
        +        return getGenericData(context, KeyRings.buildUnifiedKeyRingUri(Long.toString(masterKeyId)), proj);
        +    }
         
        -    public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) {
        -        return getPGPPublicKeyRingWithKeyId(context, keyId).getPublicKey(keyId);
        +    /** Find the master key id related to a given query. The id will either be extracted from the
        +     * query, which should work for all specific /key_rings/ queries, or will be queried if it can't.
        +     */
        +    public static long getMasterKeyId(Context context, Uri queryUri) {
        +        // try extracting from the uri first
        +        String firstSegment = queryUri.getPathSegments().get(1);
        +        if(!firstSegment.equals("find")) try {
        +            return Long.parseLong(firstSegment);
        +        } catch(NumberFormatException e) {
        +            // didn't work? oh well.
        +            Log.d(Constants.TAG, "Couldn't get masterKeyId from URI, querying...");
        +        }
        +        Object data = getGenericData(context, queryUri, KeyRings.MASTER_KEY_ID);
        +        if(data instanceof Long)
        +            return (Long) data;
        +        // TODO better error handling?
        +        return 0L;
             }
        -    public static PGPPublicKeyRing getPGPPublicKeyRingWithKeyId(Context context, long keyId) {
        -        // todo do
        -        return null;
        +
        +    public static PGPKeyRing getPGPKeyRing(Context context, Uri queryUri) {
        +        Cursor cursor = context.getContentResolver().query(queryUri,
        +                new String[]{KeyRings._ID, KeyRingData.KEY_RING_DATA}, null, null, null);
        +
        +        PGPKeyRing keyRing = null;
        +        if (cursor != null && cursor.moveToFirst()) {
        +            int keyRingDataCol = cursor.getColumnIndex(KeyRingData.KEY_RING_DATA);
        +
        +            byte[] data = cursor.getBlob(keyRingDataCol);
        +            if (data != null) {
        +                keyRing = PgpConversionHelper.BytesToPGPKeyRing(data);
        +            }
        +        }
        +
        +        if (cursor != null) {
        +            cursor.close();
        +        }
        +
        +        return keyRing;
             }
         
        -    public static PGPSecretKey getPGPSecretKeyByKeyId(Context context, long keyId) {
        -        return getPGPSecretKeyRingWithKeyId(context, keyId).getSecretKey(keyId);
        +    public static PGPPublicKeyRing getPGPPublicKeyRingWithKeyId(Context context, long keyId) {
        +        Uri uri = KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(keyId));
        +        long masterKeyId = getMasterKeyId(context, uri);
        +        if(masterKeyId != 0)
        +            return getPGPPublicKeyRing(context, masterKeyId);
        +        return null;
             }
             public static PGPSecretKeyRing getPGPSecretKeyRingWithKeyId(Context context, long keyId) {
        -        // todo do
        +        Uri uri = KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(keyId));
        +        long masterKeyId = getMasterKeyId(context, uri);
        +        if(masterKeyId != 0)
        +            return getPGPSecretKeyRing(context, masterKeyId);
                 return null;
             }
         
        @@ -332,24 +343,6 @@ public class ProviderHelper {
                 return getMasterKeyId(context, queryUri) == masterKeyId;
             }
         
        -    /** Find the master key id related to a given query. The id will either be extracted from the
        -     * query, which should work for all specific /key_rings/ queries, or will be queried if it can't.
        -     */
        -    public static long getMasterKeyId(Context context, Uri queryUri) {
        -        // try extracting from the uri first
        -        try {
        -            return Long.parseLong(queryUri.getPathSegments().get(1));
        -        } catch(NumberFormatException e) {
        -            // didn't work? oh well.
        -            Log.d(Constants.TAG, "Couldn't get masterKeyId from URI, querying...");
        -        }
        -        Object data = getUnifiedData(context, queryUri, KeyRings.MASTER_KEY_ID);
        -        if(data instanceof Long)
        -            return (Long) data;
        -        // TODO better error handling?
        -        return 0L;
        -    }
        -
             public static ArrayList getKeyRingsAsArmoredString(Context context, long[] masterKeyIds) {
                 ArrayList output = new ArrayList();
         
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
        index 007fbc99b..ccae6b2f2 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
        @@ -35,7 +35,8 @@ import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
         import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
         import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
         import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
        -import org.sufficientlysecure.keychain.provider.KeychainContract;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts;
         import org.sufficientlysecure.keychain.provider.ProviderHelper;
         import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
         import org.sufficientlysecure.keychain.service.PassphraseCacheService;
        @@ -351,7 +352,7 @@ public class OpenPgpService extends RemoteService {
                 try {
                     long keyId = data.getLongExtra(OpenPgpApi.EXTRA_KEY_ID, 0);
         
        -            if (ProviderHelper.getPGPPublicKeyByKeyId(this, keyId) == null) {
        +            if (ProviderHelper.getPGPPublicKeyRing(this, keyId) == null) {
                         Intent result = new Intent();
         
                         // If keys are not in db we return an additional PendingIntent
        @@ -460,7 +461,7 @@ public class OpenPgpService extends RemoteService {
                         String currentPkg = getCurrentCallingPackage();
                         Set allowedKeyIds =
                             ProviderHelper.getAllKeyIdsForApp(mContext,
        -                        KeychainContract.ApiAccounts.buildBaseUri(currentPkg));
        +                        ApiAccounts.buildBaseUri(currentPkg));
                         return decryptAndVerifyImpl(data, input, output, allowedKeyIds);
                     } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) {
                         return getKeyImpl(data);
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
        index 0b724d52c..f749a4c1c 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
        @@ -37,7 +37,7 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
         import org.sufficientlysecure.keychain.Id;
         import org.sufficientlysecure.keychain.R;
         import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
        -import org.sufficientlysecure.keychain.provider.KeychainContract;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
         import org.sufficientlysecure.keychain.provider.ProviderHelper;
         
         import java.util.HashMap;
        @@ -206,7 +206,7 @@ public class EncryptAsymmetricFragment extends Fragment {
                     String uidExtra = "";
                     // See if we can get a user_id from a unified query
                     Object data = ProviderHelper.getUnifiedData(
        -                    getActivity(), mSecretKeyId, KeychainContract.UserIds.USER_ID);
        +                    getActivity(), mSecretKeyId, KeyRings.USER_ID);
                     if(data instanceof String) {
                         String chunks[] = ((String) data).split(" <", 2);
                         uid = chunks[0];
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
        index ecd742896..b688dec51 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
        @@ -266,9 +266,6 @@ public class KeyListFragment extends Fragment
             static final int INDEX_IS_REVOKED = 3;
             static final int INDEX_HAS_SECRET = 4;
         
        -    // show secret before public key, sort by user id otherwise
        -    static final String SORT_ORDER = KeyRings.HAS_SECRET + " DESC, " + UserIds.USER_ID + " ASC";
        -
             @Override
             public Loader onCreateLoader(int id, Bundle args) {
                 // This is called when a new Loader needs to be created. This
        @@ -282,7 +279,7 @@ public class KeyListFragment extends Fragment
                 }
                 // Now create and return a CursorLoader that will take care of
                 // creating a Cursor for the data being displayed.
        -        return new CursorLoader(getActivity(), baseUri, PROJECTION, where, whereArgs, SORT_ORDER);
        +        return new CursorLoader(getActivity(), baseUri, PROJECTION, where, whereArgs, null);
             }
         
             @Override
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        index b60e75fa9..5760f7d8c 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        @@ -173,7 +173,9 @@ public class ViewKeyActivity extends ActionBarActivity {
             private void shareKey(Uri dataUri, boolean fingerprintOnly) {
                 String content;
                 if (fingerprintOnly) {
        -            Object blob = ProviderHelper.getUnifiedData(this, dataUri, KeychainContract.Keys.FINGERPRINT);
        +            Object blob = ProviderHelper.getGenericData(
        +                    this, KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
        +                    KeychainContract.Keys.FINGERPRINT);
                     if(blob instanceof byte[]) {
                         String fingerprint = PgpKeyHelper.convertFingerprintToHex((byte[]) blob);
                         content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
        index b8db470b4..05b571362 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
        @@ -116,7 +116,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
                     secretKey = null;
                     alert.setMessage(R.string.passphrase_for_symmetric_encryption);
                 } else {
        -            secretKey = ProviderHelper.getPGPSecretKeyByKeyId(activity, secretKeyId);
        +            secretKey = ProviderHelper.getPGPSecretKeyRing(activity, secretKeyId).getSecretKey();
         
                     if (secretKey == null) {
                         alert.setTitle(R.string.title_key_not_found);
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
        index dc9fa6235..b55645732 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
        @@ -90,7 +90,9 @@ public class ShareQrCodeDialogFragment extends DialogFragment {
                 if (mFingerprintOnly) {
                     alert.setPositiveButton(R.string.btn_okay, null);
         
        -            Object blob = ProviderHelper.getUnifiedData(getActivity(), dataUri, KeychainContract.Keys.FINGERPRINT);
        +            Object blob = ProviderHelper.getGenericData(
        +                    getActivity(), KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
        +                    KeychainContract.Keys.FINGERPRINT);
                     if(!(blob instanceof byte[])) {
                         // TODO error handling?!
                         return null;
        -- 
        cgit v1.2.3
        
        
        From d921cca91312e5888f98b178252efa2f5db103cf Mon Sep 17 00:00:00 2001
        From: Vincent Breitmoser 
        Date: Fri, 4 Apr 2014 01:07:09 +0200
        Subject: db-overhaul: reintroduce by-mail and by-subkey queries
        
        the only thing left to fix after the db upgrade (that I can think of
        right now) are key exports
        ---
         .../keychain/provider/KeychainContract.java        |  19 ++--
         .../keychain/provider/KeychainProvider.java        | 117 ++++++++++++++-------
         .../keychain/remote/OpenPgpService.java            |  16 +--
         .../keychain/service/PassphraseCacheService.java   |  13 +--
         .../keychain/ui/EncryptAsymmetricFragment.java     |  22 +---
         5 files changed, 109 insertions(+), 78 deletions(-)
        
        (limited to 'OpenPGP-Keychain/src/main/java')
        
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
        index e6e106ba6..9eeb57222 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
        @@ -83,10 +83,9 @@ public class KeychainContract {
         
             public static final String PATH_UNIFIED = "unified";
         
        -    public static final String PATH_BY_MASTER_KEY_ID = "master_key_id";
        -    public static final String PATH_BY_KEY_ID = "key_id";
        -    public static final String PATH_BY_EMAILS = "emails";
        -    public static final String PATH_BY_LIKE_EMAIL = "like_email";
        +    public static final String PATH_FIND = "find";
        +    public static final String PATH_BY_EMAIL = "email";
        +    public static final String PATH_BY_SUBKEY = "subkey";
         
             public static final String PATH_PUBLIC = "public";
             public static final String PATH_SECRET = "secret";
        @@ -109,20 +108,24 @@ public class KeychainContract {
                 public static Uri buildUnifiedKeyRingsUri() {
                     return CONTENT_URI.buildUpon().appendPath(PATH_UNIFIED).build();
                 }
        -        public static Uri buildUnifiedKeyRingsByEmailUri(String email) {
        -            return CONTENT_URI.buildUpon().appendPath("email:" + email).build();
        -        }
         
                 public static Uri buildGenericKeyRingUri(String masterKeyId) {
                     return CONTENT_URI.buildUpon().appendPath(masterKeyId).build();
                 }
        -
                 public static Uri buildUnifiedKeyRingUri(String masterKeyId) {
                     return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_UNIFIED).build();
                 }
                 public static Uri buildUnifiedKeyRingUri(Uri uri) {
                     return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_UNIFIED).build();
                 }
        +
        +        public static Uri buildUnifiedKeyRingsFindByEmailUri(String email) {
        +            return CONTENT_URI.buildUpon().appendPath(PATH_FIND).appendPath(PATH_BY_EMAIL).appendPath(email).build();
        +        }
        +        public static Uri buildUnifiedKeyRingsFindBySubkeyUri(String subkey) {
        +            return CONTENT_URI.buildUpon().appendPath(PATH_FIND).appendPath(PATH_BY_SUBKEY).appendPath(subkey).build();
        +        }
        +
             }
         
             public static class KeyRingData implements KeyRingsColumns, BaseColumns {
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
        index 8b1ee4886..a14b5b3de 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
        @@ -57,7 +57,10 @@ public class KeychainProvider extends ContentProvider {
             private static final int API_ACCOUNTS = 304;
             private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 306;
         
        -    // private static final int DATA_STREAM = 401;
        +    private static final int KEY_RINGS_FIND_BY_EMAIL = 400;
        +    private static final int KEY_RINGS_FIND_BY_SUBKEY = 401;
        +
        +    // private static final int DATA_STREAM = 501;
         
             protected UriMatcher mUriMatcher;
         
        @@ -85,6 +88,20 @@ public class KeychainProvider extends ContentProvider {
                         + "/" + KeychainContract.PATH_PUBLIC,
                         KEY_RINGS_PUBLIC);
         
        +        /**
        +         * find by criteria other than master key id
        +         *
        +         * key_rings/find/email/_
        +         * key_rings/find/subkey/_
        +         *
        +         */
        +        matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
        +                + KeychainContract.PATH_FIND + "/" + KeychainContract.PATH_BY_EMAIL + "/*",
        +                KEY_RINGS_FIND_BY_EMAIL);
        +        matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
        +                + KeychainContract.PATH_FIND + "/" + KeychainContract.PATH_BY_SUBKEY + "/*",
        +                KEY_RINGS_FIND_BY_SUBKEY);
        +
                 /**
                  * list key_ring specifics
                  *
        @@ -200,7 +217,6 @@ public class KeychainProvider extends ContentProvider {
                 Log.v(Constants.TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")");
         
                 SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        -        SQLiteDatabase db = mKeychainDatabase.getReadableDatabase();
         
                 int match = mUriMatcher.match(uri);
         
        @@ -209,7 +225,9 @@ public class KeychainProvider extends ContentProvider {
         
                 switch (match) {
                     case KEY_RING_UNIFIED:
        -            case KEY_RINGS_UNIFIED: {
        +            case KEY_RINGS_UNIFIED:
        +            case KEY_RINGS_FIND_BY_EMAIL:
        +            case KEY_RINGS_FIND_BY_SUBKEY: {
                         HashMap projectionMap = new HashMap();
                         projectionMap.put(KeyRings._ID, Tables.KEYS + ".oid AS _id");
                         projectionMap.put(KeyRings.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID);
        @@ -242,13 +260,64 @@ public class KeychainProvider extends ContentProvider {
                             );
                         qb.appendWhere(Tables.KEYS + "." + Keys.RANK + " = 0");
         
        -                if(match == KEY_RING_UNIFIED) {
        -                    qb.appendWhere(" AND " + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " = ");
        -                    qb.appendWhereEscapeString(uri.getPathSegments().get(1));
        -                } else if (TextUtils.isEmpty(sortOrder)) {
        +                switch(match) {
        +                    case KEY_RING_UNIFIED: {
        +                        qb.appendWhere(" AND " + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " = ");
        +                        qb.appendWhereEscapeString(uri.getPathSegments().get(1));
        +                        break;
        +                    }
        +                    case KEY_RINGS_FIND_BY_SUBKEY: {
        +                        try {
        +                            String subkey = Long.valueOf(uri.getLastPathSegment()).toString();
        +                            qb.appendWhere(" AND EXISTS ("
        +                                    + " SELECT 1 FROM " + Tables.KEYS + " AS tmp"
        +                                    + " WHERE tmp." + UserIds.MASTER_KEY_ID
        +                                    + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
        +                                    + " AND tmp." + Keys.KEY_ID + " = " + subkey + ""
        +                                    + ")");
        +                        } catch(NumberFormatException e) {
        +                            Log.e(Constants.TAG, "Malformed find by subkey query!", e);
        +                            qb.appendWhere(" AND 0");
        +                        }
        +                        break;
        +                    }
        +                    case KEY_RINGS_FIND_BY_EMAIL: {
        +                        String chunks[] = uri.getLastPathSegment().split(" *, *");
        +                        boolean gotCondition = false;
        +                        String emailWhere = "";
        +                        // JAVA ♥
        +                        for (int i = 0; i < chunks.length; ++i) {
        +                            if (chunks[i].length() == 0) {
        +                                continue;
        +                            }
        +                            if (i != 0) {
        +                                emailWhere += " OR ";
        +                            }
        +                            emailWhere += "tmp." + UserIds.USER_ID + " LIKE ";
        +                            // match '*', so it has to be at the *end* of the user id
        +                            emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">");
        +                            gotCondition = true;
        +                        }
        +                        if(gotCondition) {
        +                            qb.appendWhere(" AND EXISTS ("
        +                                + " SELECT 1 FROM " + Tables.USER_IDS + " AS tmp"
        +                                    + " WHERE tmp." + UserIds.MASTER_KEY_ID
        +                                            + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
        +                                        + " AND (" + emailWhere + ")"
        +                                + ")");
        +                        } else {
        +                            // TODO better way to do this?
        +                            Log.e(Constants.TAG, "Malformed find by email query!");
        +                            qb.appendWhere(" AND 0");
        +                        }
        +                        break;
        +                    }
        +                }
        +
        +                if (TextUtils.isEmpty(sortOrder)) {
                             sortOrder =
        -                            Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + " IS NULL DESC"
        -                            + Tables.USER_IDS + "." + UserIds.USER_ID + " ASC";
        +                            Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + " IS NULL ASC, "
        +                                    + Tables.USER_IDS + "." + UserIds.USER_ID + " ASC";
                         }
         
                         // uri to watch is all /key_rings/
        @@ -256,33 +325,6 @@ public class KeychainProvider extends ContentProvider {
         
                         break;
                     }
        -            /*case SECRET_KEY_RING_BY_EMAILS:
        -            case PUBLIC_KEY_RING_BY_EMAILS:
        -                qb = buildKeyRingQuery(qb, match);
        -
        -                String emails = uri.getLastPathSegment();
        -                String chunks[] = emails.split(" *, *");
        -                boolean gotCondition = false;
        -                String emailWhere = "";
        -                for (int i = 0; i < chunks.length; ++i) {
        -                    if (chunks[i].length() == 0) {
        -                        continue;
        -                    }
        -                    if (i != 0) {
        -                        emailWhere += " OR ";
        -                    }
        -                    emailWhere += "tmp." + UserIds.USER_ID + " LIKE ";
        -                    // match '*', so it has to be at the *end* of the user id
        -                    emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">");
        -                    gotCondition = true;
        -                }
        -
        -                if (gotCondition) {
        -                    qb.appendWhere(" AND EXISTS (SELECT tmp." + Base._ID + " FROM "
        -                            + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIds.KEY_RING_ROW_ID
        -                            + " = " + Tables.KEY_RINGS + "." + Base._ID + " AND (" + emailWhere
        -                            + "))");
        -                }*/
         
                     case KEY_RING_KEYS: {
                         HashMap projectionMap = new HashMap();
        @@ -387,7 +429,7 @@ public class KeychainProvider extends ContentProvider {
         
                         break;
                     default:
        -                throw new IllegalArgumentException("Unknown URI " + uri);
        +                throw new IllegalArgumentException("Unknown URI " + uri + " (" + match + ")");
         
                 }
         
        @@ -399,6 +441,7 @@ public class KeychainProvider extends ContentProvider {
                     orderBy = sortOrder;
                 }
         
        +        SQLiteDatabase db = mKeychainDatabase.getReadableDatabase();
                 Cursor c = qb.query(db, projection, selection, selectionArgs, groupBy, having, orderBy);
         
                 // Tell the cursor what uri to watch, so it knows when its source data changes
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
        index ccae6b2f2..c640bdb7c 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
        @@ -61,15 +61,15 @@ public class OpenPgpService extends RemoteService {
                 ArrayList keyIds = new ArrayList();
         
                 boolean missingUserIdsCheck = false;
        -        boolean dublicateUserIdsCheck = false;
        +        boolean duplicateUserIdsCheck = false;
                 ArrayList missingUserIds = new ArrayList();
        -        ArrayList dublicateUserIds = new ArrayList();
        +        ArrayList duplicateUserIds = new ArrayList();
         
                 for (String email : encryptionUserIds) {
        -            Uri uri = KeychainContract.KeyRings.buildUnifiedKeyRingsByEmailUri(email);
        +            Uri uri = KeyRings.buildUnifiedKeyRingsFindByEmailUri(email);
                     Cursor cur = getContentResolver().query(uri, null, null, null, null);
                     if (cur.moveToFirst()) {
        -                long id = cur.getLong(cur.getColumnIndex(KeychainContract.KeyRings.MASTER_KEY_ID));
        +                long id = cur.getLong(cur.getColumnIndex(KeyRings.MASTER_KEY_ID));
                         keyIds.add(id);
                     } else {
                         missingUserIdsCheck = true;
        @@ -77,8 +77,8 @@ public class OpenPgpService extends RemoteService {
                         Log.d(Constants.TAG, "user id missing");
                     }
                     if (cur.moveToNext()) {
        -                dublicateUserIdsCheck = true;
        -                dublicateUserIds.add(email);
        +                duplicateUserIdsCheck = true;
        +                duplicateUserIds.add(email);
                         Log.d(Constants.TAG, "more than one user id with the same email");
                     }
                 }
        @@ -90,13 +90,13 @@ public class OpenPgpService extends RemoteService {
                 }
         
                 // allow the user to verify pub key selection
        -        if (missingUserIdsCheck || dublicateUserIdsCheck) {
        +        if (missingUserIdsCheck || duplicateUserIdsCheck) {
                     // build PendingIntent
                     Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
                     intent.setAction(RemoteServiceActivity.ACTION_SELECT_PUB_KEYS);
                     intent.putExtra(RemoteServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray);
                     intent.putExtra(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds);
        -            intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, dublicateUserIds);
        +            intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, duplicateUserIds);
                     intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
         
                     PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
        index 0ec4c1239..962b304c7 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
        @@ -46,6 +46,7 @@ import org.sufficientlysecure.keychain.Constants;
         import org.sufficientlysecure.keychain.Id;
         import org.sufficientlysecure.keychain.helper.Preferences;
         import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
        +import org.sufficientlysecure.keychain.provider.KeychainContract;
         import org.sufficientlysecure.keychain.provider.ProviderHelper;
         
         import java.util.Date;
        @@ -170,15 +171,11 @@ public class PassphraseCacheService extends Service {
                 // try to get master key id which is used as an identifier for cached passphrases
                 long masterKeyId = keyId;
                 if (masterKeyId != Id.key.symmetric) {
        -            PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(this, keyId);
        -            if (keyRing == null) {
        +            masterKeyId = ProviderHelper.getMasterKeyId(this,
        +                    KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(keyId)));
        +            // Failure
        +            if(masterKeyId == 0)
                         return null;
        -            }
        -            PGPSecretKey masterKey = keyRing.getSecretKey();
        -            if (masterKey == null) {
        -                return null;
        -            }
        -            masterKeyId = masterKey.getKeyID();
                 }
                 Log.d(TAG, "getCachedPassphraseImpl() for masterKeyId " + masterKeyId);
         
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
        index f749a4c1c..11fe4a908 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
        @@ -160,23 +160,11 @@ public class EncryptAsymmetricFragment extends Fragment {
                 if (preselectedEncryptionKeyIds != null) {
                     Vector goodIds = new Vector();
                     for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) {
        -                // TODO: don't use bouncy castle objects!
        -
        -                PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(getActivity(),
        -                        preselectedEncryptionKeyIds[i]);
        -                PGPPublicKey masterKey;
        -                if (keyRing == null) {
        -                    continue;
        -                }
        -                masterKey = keyRing.getPublicKey();
        -                if (masterKey == null) {
        -                    continue;
        -                }
        -                Vector encryptKeys = PgpKeyHelper.getUsableEncryptKeys(keyRing);
        -                if (encryptKeys.size() == 0) {
        -                    continue;
        -                }
        -                goodIds.add(masterKey.getKeyID());
        +                long id = ProviderHelper.getMasterKeyId(getActivity(),
        +                        KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(preselectedEncryptionKeyIds[i]))
        +                );
        +                // TODO check for available encrypt keys... is this even relevant?
        +                goodIds.add(id);
                     }
                     if (goodIds.size() > 0) {
                         long[] keyIds = new long[goodIds.size()];
        -- 
        cgit v1.2.3
        
        
        From 2227705d650d1e9bf3e59202a093af129c272f04 Mon Sep 17 00:00:00 2001
        From: Vincent Breitmoser 
        Date: Fri, 4 Apr 2014 05:01:35 +0200
        Subject: db-overhaul: fix loading indicators in KeyListActivity and
         ViewKeyActivity
        
        ---
         .../sufficientlysecure/keychain/pgp/PgpImportExport.java    |  2 +-
         .../keychain/provider/KeychainDatabase.java                 |  1 -
         .../keychain/provider/KeychainProvider.java                 | 13 +++++++++----
         .../org/sufficientlysecure/keychain/ui/KeyListFragment.java |  6 +++---
         .../org/sufficientlysecure/keychain/ui/ViewKeyActivity.java |  2 ++
         .../sufficientlysecure/keychain/ui/ViewKeyMainFragment.java |  8 ++++++++
         6 files changed, 23 insertions(+), 9 deletions(-)
        
        (limited to 'OpenPGP-Keychain/src/main/java')
        
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
        index 49ce8d3bb..d03f3ccc2 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
        @@ -260,7 +260,6 @@ public class PgpImportExport {
                         }
         
                         if (save) {
        -                    ProviderHelper.saveKeyRing(mContext, secretKeyRing);
                             // TODO: preserve certifications
                             // (http://osdir.com/ml/encryption.bouncy-castle.devel/2007-01/msg00054.html ?)
                             PGPPublicKeyRing newPubRing = null;
        @@ -275,6 +274,7 @@ public class PgpImportExport {
                             if (newPubRing != null) {
                                 ProviderHelper.saveKeyRing(mContext, newPubRing);
                             }
        +                    ProviderHelper.saveKeyRing(mContext, secretKeyRing);
                             // TODO: remove status returns, use exceptions!
                             status = Id.return_value.ok;
                         }
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
        index e0cf6b6c5..36e2a7962 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
        @@ -124,7 +124,6 @@ public class KeychainDatabase extends SQLiteOpenHelper {
             KeychainDatabase(Context context) {
                 super(context, DATABASE_NAME, null, DATABASE_VERSION);
         
        -
                 // make sure this is only done once, on the first instance!
                 boolean iAmIt = false;
                 synchronized(apg_hack) {
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
        index a14b5b3de..1dd6ab08f 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
        @@ -168,10 +168,15 @@ public class KeychainProvider extends ContentProvider {
             @Override
             public boolean onCreate() {
                 mUriMatcher = buildUriMatcher();
        -        mKeychainDatabase = new KeychainDatabase(getContext());
                 return true;
             }
         
        +    public KeychainDatabase getDb() {
        +        if(mKeychainDatabase == null)
        +            mKeychainDatabase = new KeychainDatabase(getContext());
        +        return mKeychainDatabase;
        +    }
        +
             /**
              * {@inheritDoc}
              */
        @@ -441,7 +446,7 @@ public class KeychainProvider extends ContentProvider {
                     orderBy = sortOrder;
                 }
         
        -        SQLiteDatabase db = mKeychainDatabase.getReadableDatabase();
        +        SQLiteDatabase db = getDb().getReadableDatabase();
                 Cursor c = qb.query(db, projection, selection, selectionArgs, groupBy, having, orderBy);
         
                 // Tell the cursor what uri to watch, so it knows when its source data changes
        @@ -465,7 +470,7 @@ public class KeychainProvider extends ContentProvider {
             public Uri insert(Uri uri, ContentValues values) {
                 Log.d(Constants.TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")");
         
        -        final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase();
        +        final SQLiteDatabase db = getDb().getWritableDatabase();
         
                 Uri rowUri = null;
                 Long keyId = null;
        @@ -538,7 +543,7 @@ public class KeychainProvider extends ContentProvider {
             public int delete(Uri uri, String additionalSelection, String[] selectionArgs) {
                 Log.v(Constants.TAG, "delete(uri=" + uri + ")");
         
        -        final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase();
        +        final SQLiteDatabase db = getDb().getWritableDatabase();
         
                 int count;
                 final int match = mUriMatcher.match(uri);
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
        index b688dec51..33ccd3a23 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
        @@ -154,9 +154,6 @@ public class KeyListFragment extends Fragment
                 } catch (ApiLevelTooLowException e) {
                 }
         
        -        // this view is made visible if no data is available
        -        mStickyList.setEmptyView(getActivity().findViewById(R.id.key_list_empty));
        -
                 /*
                  * ActionBarSherlock does not support MultiChoiceModeListener. Thus multi-selection is only
                  * available for Android >= 3.0
        @@ -291,6 +288,9 @@ public class KeyListFragment extends Fragment
         
                 mStickyList.setAdapter(mAdapter);
         
        +        // this view is made visible if no data is available
        +        mStickyList.setEmptyView(getActivity().findViewById(R.id.key_list_empty));
        +
                 // NOTE: Not supported by StickyListHeader, but reimplemented here
                 // The list should now be shown.
                 if (isResumed()) {
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        index 5760f7d8c..653114c6c 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        @@ -28,6 +28,7 @@ import android.support.v7.app.ActionBar;
         import android.support.v7.app.ActionBarActivity;
         import android.view.Menu;
         import android.view.MenuItem;
        +import android.view.Window;
         import android.widget.Toast;
         import org.sufficientlysecure.keychain.Constants;
         import org.sufficientlysecure.keychain.Id;
        @@ -59,6 +60,7 @@ public class ViewKeyActivity extends ActionBarActivity {
         
             @Override
             protected void onCreate(Bundle savedInstanceState) {
        +        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
                 super.onCreate(savedInstanceState);
         
                 mExportHelper = new ExportHelper(this);
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        index 616200800..ae8b6d595 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        @@ -30,6 +30,7 @@ import android.text.format.DateFormat;
         import android.view.LayoutInflater;
         import android.view.View;
         import android.view.ViewGroup;
        +import android.widget.LinearLayout;
         import android.widget.ListView;
         import android.widget.TextView;
         
        @@ -55,6 +56,7 @@ public class ViewKeyMainFragment extends Fragment implements
         
             public static final String ARG_DATA_URI = "uri";
         
        +    private LinearLayout mContainer;
             private TextView mName;
             private TextView mEmail;
             private TextView mComment;
        @@ -83,6 +85,7 @@ public class ViewKeyMainFragment extends Fragment implements
             public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                 View view = inflater.inflate(R.layout.view_key_main_fragment, container, false);
         
        +        mContainer = (LinearLayout) view.findViewById(R.id.container);
                 mName = (TextView) view.findViewById(R.id.name);
                 mEmail = (TextView) view.findViewById(R.id.email);
                 mComment = (TextView) view.findViewById(R.id.comment);
        @@ -121,6 +124,9 @@ public class ViewKeyMainFragment extends Fragment implements
                     return;
                 }
         
        +        getActivity().setProgressBarIndeterminateVisibility(Boolean.TRUE);
        +        mContainer.setVisibility(View.GONE);
        +
                 mDataUri = dataUri;
         
                 Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
        @@ -319,6 +325,8 @@ public class ViewKeyMainFragment extends Fragment implements
                     default:
                         break;
                 }
        +        getActivity().setProgressBarIndeterminateVisibility(Boolean.FALSE);
        +        mContainer.setVisibility(View.VISIBLE);
             }
         
             /**
        -- 
        cgit v1.2.3
        
        
        From a1e13f789364a6346a1eac85adefa3660c683a63 Mon Sep 17 00:00:00 2001
        From: Vincent Breitmoser 
        Date: Fri, 4 Apr 2014 11:38:59 +0200
        Subject: calculate nfc packet on demand only
        
        ---
         .../keychain/ui/ViewKeyActivityJB.java             | 38 ++++++++++------------
         1 file changed, 18 insertions(+), 20 deletions(-)
        
        (limited to 'OpenPGP-Keychain/src/main/java')
        
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java
        index 9bbbb6c7b..6ce7d9aa8 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java
        @@ -50,34 +50,22 @@ public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMess
             @Override
             protected void onCreate(Bundle savedInstanceState) {
                 super.onCreate(savedInstanceState);
        -
        -        initNfc(mDataUri);
             }
         
             /**
              * NFC: Initialize NFC sharing if OS and device supports it
              */
        -    private void initNfc(Uri dataUri) {
        +    private void initNfc() {
                 // check if NFC Beam is supported (>= Android 4.1)
                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                     // Check for available NFC Adapter
                     mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
                     if (mNfcAdapter != null) {
                         // init nfc
        -
        -                // get public keyring as byte array
        -                long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
        -                try {
        -                    mSharedKeyringBytes = ProviderHelper.getPGPPublicKeyRing(this, masterKeyId).getEncoded();
        -
        -                    // Register callback to set NDEF message
        -                    mNfcAdapter.setNdefPushMessageCallback(this, this);
        -                    // Register callback to listen for message-sent success
        -                    mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
        -                } catch(IOException e) {
        -                    // not much trouble, but leave a note
        -                    Log.e(Constants.TAG, "Error parsing keyring: ", e);
        -                }
        +                // Register callback to set NDEF message
        +                mNfcAdapter.setNdefPushMessageCallback(this, this);
        +                // Register callback to listen for message-sent success
        +                mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
                     }
                 }
             }
        @@ -93,9 +81,19 @@ public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMess
                  * guarantee that this activity starts when receiving a beamed message. For now, this code
                  * uses the tag dispatch system.
                  */
        -        NdefMessage msg = new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME,
        -                mSharedKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME));
        -        return msg;
        +        // get public keyring as byte array
        +        long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri);
        +        try {
        +            mSharedKeyringBytes = ProviderHelper.getPGPPublicKeyRing(this, masterKeyId).getEncoded();
        +
        +            NdefMessage msg = new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME,
        +                    mSharedKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME));
        +            return msg;
        +        } catch(IOException e) {
        +            // not much trouble, but leave a note
        +            Log.e(Constants.TAG, "Error parsing keyring: ", e);
        +            return null;
        +        }
             }
         
             /**
        -- 
        cgit v1.2.3
        
        
        From a9f868a5e74e2c540d0b71d69560b780c7e16a06 Mon Sep 17 00:00:00 2001
        From: Vincent Breitmoser 
        Date: Fri, 4 Apr 2014 11:39:23 +0200
        Subject: db-overhaul: different hack for type info (api level problem inside)
        
        ---
         .../keychain/provider/ProviderHelper.java          | 24 ++++++----------------
         1 file changed, 6 insertions(+), 18 deletions(-)
        
        (limited to 'OpenPGP-Keychain/src/main/java')
        
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
        index a81368988..6a12184fe 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
        @@ -69,26 +69,14 @@ public class ProviderHelper {
         
                 HashMap result = new HashMap(proj.length);
                 if (cursor != null && cursor.moveToFirst()) {
        -            // this is a HACK because we don't have Cursor.getType (which is api level 11)
        -            CursorWindow cursorWindow;
        -            if(cursor instanceof CursorWrapper) {
        -                cursorWindow = ((SQLiteCursor) ((CursorWrapper) cursor).getWrappedCursor()).getWindow();
        -            } else {
        -                cursorWindow = ((SQLiteCursor) cursor).getWindow();
        -            }
        -
                     int pos = 0;
                     for(String p : proj) {
        -                if (cursorWindow.isNull(0, pos)) {
        -                    result.put(p, cursor.isNull(pos));
        -                } else if (cursorWindow.isLong(0, pos)) {
        -                    result.put(p, cursor.getLong(pos));
        -                } else if (cursorWindow.isFloat(0, pos)) {
        -                    result.put(p, cursor.getFloat(pos));
        -                } else if (cursorWindow.isString(0, pos)) {
        -                    result.put(p, cursor.getString(pos));
        -                } else if (cursorWindow.isBlob(0, pos)) {
        -                    result.put(p, cursor.getBlob(pos));
        +                switch(cursor.getType(pos)) {
        +                    case Cursor.FIELD_TYPE_NULL: result.put(p, cursor.isNull(pos)); break;
        +                    case Cursor.FIELD_TYPE_INTEGER: result.put(p, cursor.getLong(pos)); break;
        +                    case Cursor.FIELD_TYPE_FLOAT: result.put(p, cursor.getFloat(pos)); break;
        +                    case Cursor.FIELD_TYPE_STRING: result.put(p, cursor.getString(pos)); break;
        +                    case Cursor.FIELD_TYPE_BLOB: result.put(p, cursor.getBlob(pos)); break;
                         }
                         pos += 1;
                     }
        -- 
        cgit v1.2.3
        
        
        From 085ce11d9cb7905d69914052fb86576805db8f01 Mon Sep 17 00:00:00 2001
        From: Vincent Breitmoser 
        Date: Fri, 4 Apr 2014 11:39:34 +0200
        Subject: db-overhaul: workaround api level 11
        
        ---
         .../keychain/provider/ProviderHelper.java          | 38 +++++++++++++---------
         .../keychain/ui/EncryptAsymmetricFragment.java     |  8 ++---
         .../keychain/ui/ViewKeyActivity.java               | 14 ++++----
         .../ui/dialog/DeleteKeyDialogFragment.java         |  2 +-
         .../ui/dialog/ShareQrCodeDialogFragment.java       | 12 +++----
         5 files changed, 42 insertions(+), 32 deletions(-)
        
        (limited to 'OpenPGP-Keychain/src/main/java')
        
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
        index 6a12184fe..581ddb378 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
        @@ -61,22 +61,30 @@ import java.util.Set;
         
         public class ProviderHelper {
         
        -    public static Object getGenericData(Context context, Uri uri, String column) {
        -        return getGenericData(context, uri, new String[] { column }).get(column);
        +    // If we ever switch to api level 11, we can ditch this whole mess!
        +    public static final int FIELD_TYPE_NULL = 1;
        +    // this is called integer to stay coherent with the constants in Cursor (api level 11)
        +    public static final int FIELD_TYPE_INTEGER = 2;
        +    public static final int FIELD_TYPE_FLOAT = 3;
        +    public static final int FIELD_TYPE_STRING = 4;
        +    public static final int FIELD_TYPE_BLOB = 5;
        +
        +    public static Object getGenericData(Context context, Uri uri, String column, int type) {
        +        return getGenericData(context, uri, new String[] { column }, new int[] { type }).get(column);
             }
        -    public static HashMap getGenericData(Context context, Uri uri, String[] proj) {
        +    public static HashMap getGenericData(Context context, Uri uri, String[] proj, int[] types) {
                 Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
         
                 HashMap result = new HashMap(proj.length);
                 if (cursor != null && cursor.moveToFirst()) {
                     int pos = 0;
                     for(String p : proj) {
        -                switch(cursor.getType(pos)) {
        -                    case Cursor.FIELD_TYPE_NULL: result.put(p, cursor.isNull(pos)); break;
        -                    case Cursor.FIELD_TYPE_INTEGER: result.put(p, cursor.getLong(pos)); break;
        -                    case Cursor.FIELD_TYPE_FLOAT: result.put(p, cursor.getFloat(pos)); break;
        -                    case Cursor.FIELD_TYPE_STRING: result.put(p, cursor.getString(pos)); break;
        -                    case Cursor.FIELD_TYPE_BLOB: result.put(p, cursor.getBlob(pos)); break;
        +                switch(types[pos]) {
        +                    case FIELD_TYPE_NULL: result.put(p, cursor.isNull(pos)); break;
        +                    case FIELD_TYPE_INTEGER: result.put(p, cursor.getLong(pos)); break;
        +                    case FIELD_TYPE_FLOAT: result.put(p, cursor.getFloat(pos)); break;
        +                    case FIELD_TYPE_STRING: result.put(p, cursor.getString(pos)); break;
        +                    case FIELD_TYPE_BLOB: result.put(p, cursor.getBlob(pos)); break;
                         }
                         pos += 1;
                     }
        @@ -89,11 +97,11 @@ public class ProviderHelper {
                 return result;
             }
         
        -    public static Object getUnifiedData(Context context, long masterKeyId, String column) {
        -        return getUnifiedData(context, masterKeyId, new String[] { column }).get(column);
        +    public static Object getUnifiedData(Context context, long masterKeyId, String column, int type) {
        +        return getUnifiedData(context, masterKeyId, new String[] { column }, new int[] { type }).get(column);
             }
        -    public static HashMap getUnifiedData(Context context, long masterKeyId, String[] proj) {
        -        return getGenericData(context, KeyRings.buildUnifiedKeyRingUri(Long.toString(masterKeyId)), proj);
        +    public static HashMap getUnifiedData(Context context, long masterKeyId, String[] proj, int[] types) {
        +        return getGenericData(context, KeyRings.buildUnifiedKeyRingUri(Long.toString(masterKeyId)), proj, types);
             }
         
             /** Find the master key id related to a given query. The id will either be extracted from the
        @@ -108,8 +116,8 @@ public class ProviderHelper {
                     // didn't work? oh well.
                     Log.d(Constants.TAG, "Couldn't get masterKeyId from URI, querying...");
                 }
        -        Object data = getGenericData(context, queryUri, KeyRings.MASTER_KEY_ID);
        -        if(data instanceof Long)
        +        Object data = getGenericData(context, queryUri, KeyRings.MASTER_KEY_ID, FIELD_TYPE_INTEGER);
        +        if(data != null)
                     return (Long) data;
                 // TODO better error handling?
                 return 0L;
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
        index 67d59ab7d..6e84211cc 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
        @@ -193,10 +193,10 @@ public class EncryptAsymmetricFragment extends Fragment {
                     String uid = getResources().getString(R.string.user_id_no_name);
                     String uidExtra = "";
                     // See if we can get a user_id from a unified query
        -            Object data = ProviderHelper.getUnifiedData(
        -                    getActivity(), mSecretKeyId, KeyRings.USER_ID);
        -            if(data instanceof String) {
        -                String chunks[] = ((String) data).split(" <", 2);
        +            String user_id = (String) ProviderHelper.getUnifiedData(
        +                    getActivity(), mSecretKeyId, KeyRings.USER_ID, ProviderHelper.FIELD_TYPE_STRING);
        +            if(user_id != null) {
        +                String chunks[] = user_id.split(" <", 2);
                         uid = chunks[0];
                         if (chunks.length > 1) {
                             uidExtra = "<" + chunks[1];
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        index d09f85c47..af1fcfe52 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        @@ -158,8 +158,10 @@ public class ViewKeyActivity extends ActionBarActivity {
             }
         
             private void updateFromKeyserver(Uri dataUri) {
        -        byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri);
        -        String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
        +        byte[] blob = (byte[]) ProviderHelper.getGenericData(
        +                this, KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
        +                KeychainContract.Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
        +        String fingerprint = PgpKeyHelper.convertFingerprintToHex(blob);
         
                 Intent queryIntent = new Intent(this, ImportKeysActivity.class);
                 queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN);
        @@ -171,11 +173,11 @@ public class ViewKeyActivity extends ActionBarActivity {
             private void shareKey(Uri dataUri, boolean fingerprintOnly) {
                 String content;
                 if (fingerprintOnly) {
        -            Object blob = ProviderHelper.getGenericData(
        +            byte[] data = (byte[]) ProviderHelper.getGenericData(
                             this, KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
        -                    KeychainContract.Keys.FINGERPRINT);
        -            if(blob instanceof byte[]) {
        -                String fingerprint = PgpKeyHelper.convertFingerprintToHex((byte[]) blob);
        +                    KeychainContract.Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
        +            if(data != null) {
        +                String fingerprint = PgpKeyHelper.convertFingerprintToHex(data);
                         content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
                     } else {
                         Toast.makeText(getApplicationContext(), "Bad key selected!",
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
        index feaa0b4cd..36123a98b 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
        @@ -106,7 +106,7 @@ public class DeleteKeyDialogFragment extends DialogFragment {
                     HashMap data = ProviderHelper.getUnifiedData(activity, masterKeyId, new String[]{
                             KeyRings.USER_ID,
                             KeyRings.HAS_SECRET
        -            });
        +            }, new int[] { ProviderHelper.FIELD_TYPE_STRING, ProviderHelper.FIELD_TYPE_INTEGER });
                     String userId = (String) data.get(KeyRings.USER_ID);
                     boolean hasSecret = ((Long) data.get(KeyRings.HAS_SECRET)) == 1;
         
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
        index b55645732..b6ff139df 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
        @@ -31,7 +31,7 @@ import android.widget.TextView;
         import org.sufficientlysecure.keychain.Constants;
         import org.sufficientlysecure.keychain.R;
         import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
        -import org.sufficientlysecure.keychain.provider.KeychainContract;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
         import org.sufficientlysecure.keychain.provider.ProviderHelper;
         import org.sufficientlysecure.keychain.util.QrCodeUtils;
         
        @@ -90,15 +90,15 @@ public class ShareQrCodeDialogFragment extends DialogFragment {
                 if (mFingerprintOnly) {
                     alert.setPositiveButton(R.string.btn_okay, null);
         
        -            Object blob = ProviderHelper.getGenericData(
        -                    getActivity(), KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
        -                    KeychainContract.Keys.FINGERPRINT);
        -            if(!(blob instanceof byte[])) {
        +            byte[] blob = (byte[]) ProviderHelper.getGenericData(
        +                    getActivity(), KeyRings.buildUnifiedKeyRingUri(dataUri),
        +                    KeyRings.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
        +            if(blob == null) {
                         // TODO error handling?!
                         return null;
                     }
         
        -            String fingerprint = PgpKeyHelper.convertFingerprintToHex((byte[]) blob);
        +            String fingerprint = PgpKeyHelper.convertFingerprintToHex(blob);
                     mText.setText(getString(R.string.share_qr_code_dialog_fingerprint_text) + " " + fingerprint);
                     content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
                     setQrCode(content);
        -- 
        cgit v1.2.3
        
        
        From 958eba1c95d1d25c51e8891ff5f2b8d49735e64d Mon Sep 17 00:00:00 2001
        From: Vincent Breitmoser 
        Date: Fri, 4 Apr 2014 13:58:12 +0200
        Subject: db-overhaul: fix DecryptAndVerify with and without known keys
        
        ---
         .../keychain/pgp/PgpDecryptVerify.java             | 110 +++++++++++----------
         1 file changed, 59 insertions(+), 51 deletions(-)
        
        (limited to 'OpenPGP-Keychain/src/main/java')
        
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
        index 4b0a07d9b..8a0bf99d7 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
        @@ -53,6 +53,7 @@ import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactory
         import org.sufficientlysecure.keychain.Constants;
         import org.sufficientlysecure.keychain.R;
         import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
         import org.sufficientlysecure.keychain.provider.ProviderHelper;
         import org.sufficientlysecure.keychain.service.PassphraseCacheService;
         import org.sufficientlysecure.keychain.util.InputData;
        @@ -66,6 +67,7 @@ import java.io.IOException;
         import java.io.InputStream;
         import java.io.OutputStream;
         import java.security.SignatureException;
        +import java.util.HashMap;
         import java.util.Iterator;
         import java.util.Set;
         
        @@ -232,47 +234,51 @@ public class PgpDecryptVerify {
                         updateProgress(R.string.progress_finding_key, currentProgress, 100);
         
                         PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
        -                secretKey = ProviderHelper.getPGPSecretKeyRing(mContext, encData.getKeyID()).getSecretKey();
        -                if (secretKey != null) {
        -                    // secret key exists in database
        -
        -                    // allow only a specific key for decryption?
        -                    if (mAllowedKeyIds != null) {
        -                        // TODO: improve this code! get master key directly!
        -                        PGPSecretKeyRing secretKeyRing =
        -                                ProviderHelper.getPGPSecretKeyRingWithKeyId(mContext, encData.getKeyID());
        -                        long masterKeyId = secretKeyRing.getSecretKey().getKeyID();
        -                        Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID());
        -                        Log.d(Constants.TAG, "allowedKeyIds: " + mAllowedKeyIds);
        -                        Log.d(Constants.TAG, "masterKeyId: " + masterKeyId);
        -
        -                        if (!mAllowedKeyIds.contains(masterKeyId)) {
        -                            throw new PgpGeneralException(
        -                                    mContext.getString(R.string.error_no_secret_key_found));
        -                        }
        +                long masterKeyId = ProviderHelper.getMasterKeyId(mContext,
        +                        KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(encData.getKeyID()))
        +                );
        +                PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRing(mContext, masterKeyId);
        +                if (secretKeyRing == null) {
        +                    throw new PgpGeneralException(mContext.getString(R.string.error_no_secret_key_found));
        +                }
        +                secretKey = secretKeyRing.getSecretKey(encData.getKeyID());
        +                if (secretKey == null) {
        +                    throw new PgpGeneralException(mContext.getString(R.string.error_no_secret_key_found));
        +                }
        +                // secret key exists in database
        +
        +                // allow only a specific key for decryption?
        +                if (mAllowedKeyIds != null) {
        +                    Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID());
        +                    Log.d(Constants.TAG, "allowedKeyIds: " + mAllowedKeyIds);
        +                    Log.d(Constants.TAG, "masterKeyId: " + masterKeyId);
        +
        +                    if (!mAllowedKeyIds.contains(masterKeyId)) {
        +                        throw new PgpGeneralException(
        +                                mContext.getString(R.string.error_no_secret_key_found));
                             }
        +                }
         
        -                    encryptedDataAsymmetric = encData;
        +                encryptedDataAsymmetric = encData;
         
        -                    // if no passphrase was explicitly set try to get it from the cache service
        +                // if no passphrase was explicitly set try to get it from the cache service
        +                if (mPassphrase == null) {
        +                    // returns "" if key has no passphrase
        +                    mPassphrase =
        +                            PassphraseCacheService.getCachedPassphrase(mContext, masterKeyId);
        +
        +                    // if passphrase was not cached, return here
        +                    // indicating that a passphrase is missing!
                             if (mPassphrase == null) {
        -                        // returns "" if key has no passphrase
        -                        mPassphrase =
        -                                PassphraseCacheService.getCachedPassphrase(mContext, encData.getKeyID());
        -
        -                        // if passphrase was not cached, return here
        -                        // indicating that a passphrase is missing!
        -                        if (mPassphrase == null) {
        -                            returnData.setKeyIdPassphraseNeeded(encData.getKeyID());
        -                            returnData.setStatus(PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED);
        -                            return returnData;
        -                        }
        +                        returnData.setKeyIdPassphraseNeeded(masterKeyId);
        +                        returnData.setStatus(PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED);
        +                        return returnData;
                             }
        -
        -                    // break out of while, only get first object here
        -                    // TODO???: There could be more pgp objects, which are not decrypted!
        -                    break;
                         }
        +
        +                // break out of while, only get first object here
        +                // TODO???: There could be more pgp objects, which are not decrypted!
        +                break;
                     } else if (mAllowSymmetricDecryption && obj instanceof PGPPBEEncryptedData) {
                         symmetricPacketFound = true;
         
        @@ -545,25 +551,27 @@ public class PgpDecryptVerify {
                 long signatureKeyId = 0;
                 PGPPublicKey signatureKey = null;
                 for (int i = 0; i < sigList.size(); ++i) {
        -            signature = sigList.get(i);
        -            signatureKey = ProviderHelper.getPGPPublicKeyRing(mContext, signature.getKeyID()).getPublicKey();
        -            if (signatureKeyId == 0) {
        -                signatureKeyId = signature.getKeyID();
        -            }
         
        -            if (signatureKey == null) {
        +            signature = sigList.get(i);
        +            signatureKeyId = signature.getKeyID();
        +
        +            // find data about this subkey
        +            HashMap data = ProviderHelper.getGenericData(mContext,
        +                    KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(signature.getKeyID())),
        +                    new String[] { KeyRings.MASTER_KEY_ID, KeyRings.USER_ID },
        +                    new int[] { ProviderHelper.FIELD_TYPE_INTEGER, ProviderHelper.FIELD_TYPE_STRING });
        +            // any luck? otherwise, try next.
        +            if(data.get(KeyRings.MASTER_KEY_ID) == null) {
                         signature = null;
        -            } else {
        -                signatureKeyId = signature.getKeyID();
        -                String userId = null;
        -                PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(mContext,
        -                        signatureKeyId);
        -                if (signKeyRing != null) {
        -                    userId = PgpKeyHelper.getMainUserId(signKeyRing.getPublicKey());
        -                }
        -                signatureResult.setUserId(userId);
        -                break;
        +                // do NOT reset signatureKeyId, that one is shown when no known one is found!
        +                continue;
                     }
        +
        +            // this one can't fail now (yay database constraints)
        +            signatureKey = ProviderHelper.getPGPPublicKeyRing(mContext, (Long) data.get(KeyRings.MASTER_KEY_ID)).getPublicKey();
        +            signatureResult.setUserId((String) data.get(KeyRings.USER_ID));
        +
        +            break;
                 }
         
                 signatureResult.setKeyId(signatureKeyId);
        -- 
        cgit v1.2.3
        
        
        From 53e8afaee035c6421c9b4efefea2d6171c6183b8 Mon Sep 17 00:00:00 2001
        From: Vincent Breitmoser 
        Date: Fri, 4 Apr 2014 14:37:07 +0200
        Subject: ViewKeyMainFragment cleanup (don't use inline queries!)
        
        ---
         .../keychain/ui/ViewKeyMainFragment.java           | 173 +++++++++------------
         1 file changed, 77 insertions(+), 96 deletions(-)
        
        (limited to 'OpenPGP-Keychain/src/main/java')
        
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        index ae8b6d595..5f30848f8 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        @@ -73,6 +73,7 @@ public class ViewKeyMainFragment extends Fragment implements
             private ListView mUserIds;
             private ListView mKeys;
         
        +    private static final int LOADER_ID_UNIFIED = 0;
             private static final int LOADER_ID_USER_IDS = 1;
             private static final int LOADER_ID_KEYS = 2;
         
        @@ -131,60 +132,17 @@ public class ViewKeyMainFragment extends Fragment implements
         
                 Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
         
        -        { // label whether secret key is available, and edit button if it is
        -            final long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), mDataUri);
        -            // TODO do this some other way...
        -            if (ProviderHelper.hasSecretKeyByMasterKeyId(getActivity(), masterKeyId)) {
        -                // set this attribute. this is a LITTLE unclean, but we have the info available
        -                // right here, so why not.
        -                mSecretKey.setTextColor(getResources().getColor(R.color.emphasis));
        -                mSecretKey.setText(R.string.secret_key_yes);
        -
        -                // certify button
        -                // TODO this button MIGHT be useful if the user wants to
        -                // certify a private key with another...
        -                // mActionCertify.setVisibility(View.GONE);
        -
        -                // edit button
        -                mActionEdit.setVisibility(View.VISIBLE);
        -                mActionEdit.setOnClickListener(new View.OnClickListener() {
        -                    public void onClick(View view) {
        -                        Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
        -                        editIntent.setData(
        -                                KeyRingData.buildSecretKeyRingUri(
        -                                        Long.toString(masterKeyId)));
        -                        editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
        -                        startActivityForResult(editIntent, 0);
        -                    }
        -                });
        -            } else {
        -                mSecretKey.setTextColor(Color.BLACK);
        -                mSecretKey.setText(getResources().getString(R.string.secret_key_no));
        -
        -                // certify button
        -                mActionCertify.setVisibility(View.VISIBLE);
        -                // edit button
        -                mActionEdit.setVisibility(View.GONE);
        -            }
        -
        -            // TODO see todo note above, doing this here for now
        -            mActionCertify.setOnClickListener(new View.OnClickListener() {
        -                public void onClick(View view) {
        -                    certifyKey(KeyRings.buildGenericKeyRingUri(
        -                            Long.toString(masterKeyId)
        -                    ));
        -                }
        -            });
        -
        -        }
        -
                 mActionEncrypt.setOnClickListener(new View.OnClickListener() {
        -
                     @Override
                     public void onClick(View v) {
                         encryptToContact(mDataUri);
                     }
                 });
        +        mActionCertify.setOnClickListener(new View.OnClickListener() {
        +            public void onClick(View view) {
        +                certifyKey(mDataUri);
        +            }
        +        });
         
                 mUserIdsAdapter = new ViewKeyUserIdsAdapter(getActivity(), null, 0);
                 mUserIds.setAdapter(mUserIdsAdapter);
        @@ -194,49 +152,50 @@ public class ViewKeyMainFragment extends Fragment implements
         
                 // Prepare the loaders. Either re-connect with an existing ones,
                 // or start new ones.
        +        getActivity().getSupportLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
                 getActivity().getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
                 getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
             }
         
        -    static final String[] USER_IDS_PROJECTION =
        -            new String[] {
        -                    UserIds._ID,
        -                    UserIds.USER_ID,
        -                    UserIds.RANK,
        -            };
        -    static final int INDEX_UID_UID = 1;
        +    static final String[] UNIFIED_PROJECTION = new String[] {
        +        KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_SECRET,
        +            KeyRings.USER_ID, KeyRings.FINGERPRINT,
        +            KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.EXPIRY,
        +
        +    };
        +    static final int INDEX_UNIFIED_MKI = 1;
        +    static final int INDEX_UNIFIED_HAS_SECRET = 2;
        +    static final int INDEX_UNIFIED_UID = 3;
        +    static final int INDEX_UNIFIED_FINGERPRINT = 4;
        +    static final int INDEX_UNIFIED_ALGORITHM = 5;
        +    static final int INDEX_UNIFIED_KEY_SIZE = 6;
        +    static final int INDEX_UNIFIED_CREATION = 7;
        +    static final int INDEX_UNIFIED_EXPIRY = 8;
        +
        +    static final String[] USER_IDS_PROJECTION = new String[] {
        +        UserIds._ID, UserIds.USER_ID, UserIds.RANK,
        +    };
         
             static final String[] KEYS_PROJECTION = new String[] {
                     Keys._ID,
        -            Keys.KEY_ID, Keys.RANK,
        -            Keys.ALGORITHM, Keys.KEY_SIZE,
        -            Keys.CAN_CERTIFY, Keys.CAN_ENCRYPT,
        -            Keys.CAN_SIGN, Keys.IS_REVOKED,
        -            Keys.CREATION, Keys.EXPIRY,
        -            Keys.FINGERPRINT
        +            Keys.KEY_ID, Keys.RANK, Keys.ALGORITHM, Keys.KEY_SIZE,
        +            Keys.CAN_CERTIFY, Keys.CAN_ENCRYPT, Keys.CAN_SIGN, Keys.IS_REVOKED,
        +            Keys.CREATION, Keys.EXPIRY, Keys.FINGERPRINT
             };
        -    static final int KEYS_INDEX_KEY_ID = 1;
        -    static final int KEYS_INDEX_ALGORITHM = 3;
        -    static final int KEYS_INDEX_KEY_SIZE = 4;
             static final int KEYS_INDEX_CAN_ENCRYPT = 6;
        -    static final int KEYS_INDEX_CREATION = 9;
        -    static final int KEYS_INDEX_EXPIRY = 10;
        -    static final int KEYS_INDEX_FINGERPRINT = 11;
         
             public Loader onCreateLoader(int id, Bundle args) {
                 switch (id) {
        +            case LOADER_ID_UNIFIED: {
        +                Uri baseUri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
        +                return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null);
        +            }
                     case LOADER_ID_USER_IDS: {
                         Uri baseUri = UserIds.buildUserIdsUri(mDataUri);
        -
        -                // Now create and return a CursorLoader that will take care of
        -                // creating a Cursor for the data being displayed.
                         return new CursorLoader(getActivity(), baseUri, USER_IDS_PROJECTION, null, null, null);
                     }
                     case LOADER_ID_KEYS: {
                         Uri baseUri = Keys.buildKeysUri(mDataUri);
        -
        -                // Now create and return a CursorLoader that will take care of
        -                // creating a Cursor for the data being displayed.
                         return new CursorLoader(getActivity(), baseUri, KEYS_PROJECTION, null, null, null);
                     }
         
        @@ -249,11 +208,10 @@ public class ViewKeyMainFragment extends Fragment implements
                 // Swap the new cursor in. (The framework will take care of closing the
                 // old cursor once we return.)
                 switch (loader.getId()) {
        -            case LOADER_ID_USER_IDS:
        +            case LOADER_ID_UNIFIED: {
                         if (data.moveToFirst()) {
                             // get name, email, and comment from USER_ID
        -                    String[] mainUserId = PgpKeyHelper.splitUserId(data
        -                            .getString(INDEX_UID_UID));
        +                    String[] mainUserId = PgpKeyHelper.splitUserId(data.getString(INDEX_UNIFIED_UID));
                             if (mainUserId[0] != null) {
                                 getActivity().setTitle(mainUserId[0]);
                                 mName.setText(mainUserId[0]);
        @@ -263,22 +221,43 @@ public class ViewKeyMainFragment extends Fragment implements
                             }
                             mEmail.setText(mainUserId[1]);
                             mComment.setText(mainUserId[2]);
        -                }
        -                mUserIdsAdapter.swapCursor(data);
        -                break;
        -            case LOADER_ID_KEYS:
        -                // the first key here is our master key
        -                if (data.moveToFirst()) {
        +
        +                    if (data.getInt(INDEX_UNIFIED_HAS_SECRET) > 0) {
        +                        // set this attribute. this is a LITTLE unclean, but we have the info available
        +                        // right here, so why not.
        +                        mSecretKey.setTextColor(getResources().getColor(R.color.emphasis));
        +                        mSecretKey.setText(R.string.secret_key_yes);
        +
        +                        // edit button
        +                        mActionEdit.setVisibility(View.VISIBLE);
        +                        mActionEdit.setOnClickListener(new View.OnClickListener() {
        +                            public void onClick(View view) {
        +                                Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
        +                                editIntent.setData(mDataUri);
        +                                editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
        +                                startActivityForResult(editIntent, 0);
        +                            }
        +                        });
        +                    } else {
        +                        mSecretKey.setTextColor(Color.BLACK);
        +                        mSecretKey.setText(getResources().getString(R.string.secret_key_no));
        +
        +                        // certify button
        +                        mActionCertify.setVisibility(View.VISIBLE);
        +                        // edit button
        +                        mActionEdit.setVisibility(View.GONE);
        +                    }
        +
                             // get key id from MASTER_KEY_ID
        -                    long keyId = data.getLong(KEYS_INDEX_KEY_ID);
        -                    String keyIdStr = PgpKeyHelper.convertKeyIdToHex(keyId);
        +                    long masterKeyId = data.getLong(INDEX_UNIFIED_MKI);
        +                    String keyIdStr = PgpKeyHelper.convertKeyIdToHex(masterKeyId);
                             mKeyId.setText(keyIdStr);
         
                             // get creation date from CREATION
        -                    if (data.isNull(KEYS_INDEX_CREATION)) {
        +                    if (data.isNull(INDEX_UNIFIED_CREATION)) {
                                 mCreation.setText(R.string.none);
                             } else {
        -                        Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000);
        +                        Date creationDate = new Date(data.getLong(INDEX_UNIFIED_CREATION) * 1000);
         
                                 mCreation.setText(
                                         DateFormat.getDateFormat(getActivity().getApplicationContext()).format(
        @@ -286,10 +265,10 @@ public class ViewKeyMainFragment extends Fragment implements
                             }
         
                             // get expiry date from EXPIRY
        -                    if (data.isNull(KEYS_INDEX_EXPIRY)) {
        +                    if (data.isNull(INDEX_UNIFIED_EXPIRY)) {
                                 mExpiry.setText(R.string.none);
                             } else {
        -                        Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000);
        +                        Date expiryDate = new Date(data.getLong(INDEX_UNIFIED_EXPIRY) * 1000);
         
                                 mExpiry.setText(
                                         DateFormat.getDateFormat(getActivity().getApplicationContext()).format(
        @@ -297,15 +276,22 @@ public class ViewKeyMainFragment extends Fragment implements
                             }
         
                             String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
        -                            data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE));
        +                            data.getInt(INDEX_UNIFIED_ALGORITHM), data.getInt(INDEX_UNIFIED_KEY_SIZE));
                             mAlgorithm.setText(algorithmStr);
         
        -                    byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
        +                    byte[] fingerprintBlob = data.getBlob(INDEX_UNIFIED_FINGERPRINT);
                             String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
        -
                             mFingerprint.setText(PgpKeyHelper.colorizeFingerprint(fingerprint));
        +
        +                    break;
                         }
        +            }
         
        +            case LOADER_ID_USER_IDS:
        +                mUserIdsAdapter.swapCursor(data);
        +                break;
        +
        +            case LOADER_ID_KEYS:
                         // hide encrypt button if no encryption key is available
                         boolean canEncrypt = false;
                         data.moveToFirst();
        @@ -321,9 +307,6 @@ public class ViewKeyMainFragment extends Fragment implements
         
                         mKeysAdapter.swapCursor(data);
                         break;
        -
        -            default:
        -                break;
                 }
                 getActivity().setProgressBarIndeterminateVisibility(Boolean.FALSE);
                 mContainer.setVisibility(View.VISIBLE);
        @@ -341,8 +324,6 @@ public class ViewKeyMainFragment extends Fragment implements
                     case LOADER_ID_KEYS:
                         mKeysAdapter.swapCursor(null);
                         break;
        -            default:
        -                break;
                 }
             }
         
        -- 
        cgit v1.2.3
        
        
        From cf76a8553a686e1e9c8757b39b6b4e3c4b05bb0c Mon Sep 17 00:00:00 2001
        From: Vincent Breitmoser 
        Date: Fri, 4 Apr 2014 16:28:28 +0200
        Subject: db-overhaul: fix delete key from ViewKeyActivity
        
        ---
         .../sufficientlysecure/keychain/helper/ExportHelper.java    |  7 +++----
         .../sufficientlysecure/keychain/ui/ViewKeyMainFragment.java |  7 ++++++-
         .../keychain/ui/dialog/DeleteKeyDialogFragment.java         | 13 +++----------
         3 files changed, 12 insertions(+), 15 deletions(-)
        
        (limited to 'OpenPGP-Keychain/src/main/java')
        
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java
        index 43fdc7751..3040b4e9c 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java
        @@ -30,6 +30,7 @@ import org.sufficientlysecure.keychain.Constants;
         import org.sufficientlysecure.keychain.Id;
         import org.sufficientlysecure.keychain.R;
         import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
        +import org.sufficientlysecure.keychain.provider.ProviderHelper;
         import org.sufficientlysecure.keychain.service.KeychainIntentService;
         import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
         import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
        @@ -48,14 +49,12 @@ public class ExportHelper {
             }
         
             public void deleteKey(Uri dataUri, Handler deleteHandler) {
        -        long keyRingRowId = Long.valueOf(dataUri.getLastPathSegment());
        -
                 // Create a new Messenger for the communication back
                 Messenger messenger = new Messenger(deleteHandler);
        +        long masterKeyId = ProviderHelper.getMasterKeyId(mActivity, dataUri);
         
                 DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
        -                new long[]{keyRingRowId});
        -
        +                new long[]{ masterKeyId });
                 deleteKeyDialog.show(mActivity.getSupportFragmentManager(), "deleteKeyDialog");
             }
         
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        index 5f30848f8..3c6ae514e 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        @@ -42,7 +42,6 @@ import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
         import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
         import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
         import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
        -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
         import org.sufficientlysecure.keychain.provider.ProviderHelper;
         import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter;
         import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter;
        @@ -205,6 +204,12 @@ public class ViewKeyMainFragment extends Fragment implements
             }
         
             public void onLoadFinished(Loader loader, Cursor data) {
        +        /* TODO better error handling? May cause problems when a key is deleted,
        +         * because the notification triggers faster than the activity closes.
        +         */
        +        // Avoid NullPointerExceptions...
        +        if(data.getCount() == 0)
        +            return;
                 // Swap the new cursor in. (The framework will take care of closing the
                 // old cursor once we return.)
                 switch (loader.getId()) {
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
        index 36123a98b..72ea4c013 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
        @@ -75,7 +75,6 @@ public class DeleteKeyDialogFragment extends DialogFragment {
                 return frag;
             }
         
        -
             @Override
             public Dialog onCreateDialog(Bundle savedInstanceState) {
         
        @@ -122,7 +121,6 @@ public class DeleteKeyDialogFragment extends DialogFragment {
                     mMainMessage.setText(R.string.key_deletion_confirmation_multi);
                 }
         
        -
                 builder.setIcon(R.drawable.ic_dialog_alert_holo_light);
                 builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
                     @Override
        @@ -133,21 +131,16 @@ public class DeleteKeyDialogFragment extends DialogFragment {
                             int count = activity.getContentResolver().delete(
                                     KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null
                                 );
        -                    if(count > 0)
        -                    success = true;
        +                    success = count > 0;
                         }
        -
        -                dismiss();
        -
                         if (success) {
                             sendMessageToHandler(MESSAGE_OKAY, null);
                         } else {
                             sendMessageToHandler(MESSAGE_ERROR, null);
                         }
        +                dismiss();
                     }
        -
        -        }
        -        );
        +        });
                 builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
         
                     @Override
        -- 
        cgit v1.2.3
        
        
        From a523f53a96ec1b6be10e46670f4f5a5001634f7e Mon Sep 17 00:00:00 2001
        From: Thialfihar 
        Date: Wed, 2 Apr 2014 20:53:34 +0200
        Subject: Simplify PassphraseDialogFragment usage
        
        Move boiler plate code into a simple static show() method, which only
        requires a Handler and can be used ad hoc in any FragmentActivity.
        ---
         .../keychain/remote/ui/RemoteServiceActivity.java  | 18 ++++++++-
         .../keychain/ui/CertifyKeyActivity.java            | 37 +++++-------------
         .../keychain/ui/DecryptFragment.java               | 37 +++++-------------
         .../keychain/ui/EditKeyActivity.java               | 42 ++++++---------------
         .../keychain/ui/EncryptFileFragment.java           | 41 +++++---------------
         .../keychain/ui/EncryptMessageFragment.java        | 44 +++++-----------------
         .../ui/dialog/PassphraseDialogFragment.java        | 23 +++++++++++
         7 files changed, 89 insertions(+), 153 deletions(-)
        
        (limited to 'OpenPGP-Keychain/src/main/java')
        
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
        index b2ab75cea..307c9c61a 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
        @@ -178,9 +178,23 @@ public class RemoteServiceActivity extends ActionBarActivity {
                     mAccSettingsFragment.setAccSettings(settings);
                 } else if (ACTION_CACHE_PASSPHRASE.equals(action)) {
                     long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID);
        -            Intent resultData = extras.getParcelable(EXTRA_DATA);
        +            final Intent resultData = extras.getParcelable(EXTRA_DATA);
        +
        +            PassphraseDialogFragment.show(this, secretKeyId,
        +                new Handler() {
        +                    @Override
        +                    public void handleMessage(Message message) {
        +                        if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
        +                            // return given params again, for calling the service method again
        +                            RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
        +                        } else {
        +                            RemoteServiceActivity.this.setResult(RESULT_CANCELED);
        +                        }
        +
        +                        RemoteServiceActivity.this.finish();
        +                    }
        +                });
         
        -            showPassphraseDialog(resultData, secretKeyId);
                 } else if (ACTION_SELECT_PUB_KEYS.equals(action)) {
                     long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
                     ArrayList missingUserIds = intent
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
        index dbd3af466..fb8726ace 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
        @@ -46,7 +46,6 @@ import org.sufficientlysecure.keychain.Constants;
         import org.sufficientlysecure.keychain.R;
         import org.sufficientlysecure.keychain.helper.Preferences;
         import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
        -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
         import org.sufficientlysecure.keychain.provider.KeychainContract;
         import org.sufficientlysecure.keychain.provider.ProviderHelper;
         import org.sufficientlysecure.keychain.service.KeychainIntentService;
        @@ -224,32 +223,6 @@ public class CertifyKeyActivity extends ActionBarActivity implements
                 }
             }
         
        -    private void showPassphraseDialog(final long secretKeyId) {
        -        // Message is received after passphrase is cached
        -        Handler returnHandler = new Handler() {
        -            @Override
        -            public void handleMessage(Message message) {
        -                if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
        -                    startSigning();
        -                }
        -            }
        -        };
        -
        -        // Create a new Messenger for the communication back
        -        Messenger messenger = new Messenger(returnHandler);
        -
        -        try {
        -            PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(this,
        -                    messenger, secretKeyId);
        -
        -            passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
        -        } catch (PgpGeneralException e) {
        -            Log.d(Constants.TAG, "No passphrase for this secret key!");
        -            // send message to handler to start certification directly
        -            returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
        -        }
        -    }
        -
             /**
              * handles the UI bits of the signing process on the UI thread
              */
        @@ -277,7 +250,15 @@ public class CertifyKeyActivity extends ActionBarActivity implements
                          */
                         String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId);
                         if (passphrase == null) {
        -                    showPassphraseDialog(mMasterKeyId);
        +                    PassphraseDialogFragment.show(this, mMasterKeyId,
        +                        new Handler() {
        +                            @Override
        +                            public void handleMessage(Message message) {
        +                                if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
        +                                    startSigning();
        +                                }
        +                            }
        +                        });
                             // bail out; need to wait until the user has entered the passphrase before trying again
                             return;
                         } else {
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
        index e7596534c..1c465f55c 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
        @@ -22,7 +22,6 @@ import android.content.Intent;
         import android.os.Bundle;
         import android.os.Handler;
         import android.os.Message;
        -import android.os.Messenger;
         import android.support.v4.app.Fragment;
         import android.view.View;
         import android.view.View.OnClickListener;
        @@ -34,14 +33,12 @@ import com.beardedhen.androidbootstrap.BootstrapButton;
         import com.devspark.appmsg.AppMsg;
         
         import org.openintents.openpgp.OpenPgpSignatureResult;
        -import org.sufficientlysecure.keychain.Constants;
         import org.sufficientlysecure.keychain.R;
         import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
         import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
         import org.sufficientlysecure.keychain.provider.KeychainContract;
         import org.sufficientlysecure.keychain.provider.ProviderHelper;
         import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
        -import org.sufficientlysecure.keychain.util.Log;
         
         public class DecryptFragment extends Fragment {
             private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
        @@ -158,31 +155,17 @@ public class DecryptFragment extends Fragment {
             }
         
             protected void showPassphraseDialog(long keyId) {
        -        // Message is received after passphrase is cached
        -        Handler returnHandler = new Handler() {
        -            @Override
        -            public void handleMessage(Message message) {
        -                if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
        -                    String passphrase =
        -                            message.getData().getString(PassphraseDialogFragment.MESSAGE_DATA_PASSPHRASE);
        -                    decryptStart(passphrase);
        +        PassphraseDialogFragment.show(getActivity(), keyId,
        +            new Handler() {
        +                @Override
        +                public void handleMessage(Message message) {
        +                    if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
        +                        String passphrase =
        +                                message.getData().getString(PassphraseDialogFragment.MESSAGE_DATA_PASSPHRASE);
        +                        decryptStart(passphrase);
        +                    }
                         }
        -            }
        -        };
        -
        -        // Create a new Messenger for the communication back
        -        Messenger messenger = new Messenger(returnHandler);
        -
        -        try {
        -            PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(getActivity(),
        -                    messenger, keyId);
        -
        -            passphraseDialog.show(getActivity().getSupportFragmentManager(), "passphraseDialog");
        -        } catch (PgpGeneralException e) {
        -            Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
        -            // send message to handler to start encryption directly
        -            returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
        -        }
        +            });
             }
         
             /**
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
        index d7ff8c207..c44686cb1 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
        @@ -282,34 +282,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
                 }
             }
         
        -    private void showPassphraseDialog(final long masterKeyId) {
        -        // Message is received after passphrase is cached
        -        Handler returnHandler = new Handler() {
        -            @Override
        -            public void handleMessage(Message message) {
        -                if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
        -                    mCurrentPassphrase = PassphraseCacheService.getCachedPassphrase(
        -                            EditKeyActivity.this, masterKeyId);
        -                    checkEmptyIDsWanted();
        -                }
        -            }
        -        };
        -
        -        // Create a new Messenger for the communication back
        -        Messenger messenger = new Messenger(returnHandler);
        -
        -        try {
        -            PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(
        -                    EditKeyActivity.this, messenger, masterKeyId);
        -
        -            passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
        -        } catch (PgpGeneralException e) {
        -            Log.d(Constants.TAG, "No passphrase for this secret key!");
        -            // send message to handler to start encryption directly
        -            returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
        -        }
        -    }
        -
             @Override
             public boolean onCreateOptionsMenu(Menu menu) {
                 super.onCreateOptionsMenu(menu);
        @@ -539,7 +511,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
             }
         
             private void saveClicked() {
        -        long masterKeyId = getMasterKeyId();
        +        final long masterKeyId = getMasterKeyId();
                 if (needsSaving()) { //make sure, as some versions don't support invalidateOptionsMenu
                     try {
                         if (!isPassphraseSet()) {
        @@ -553,7 +525,17 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
                             passphrase = "";
                         }
                         if (passphrase == null) {
        -                    showPassphraseDialog(masterKeyId);
        +                    PassphraseDialogFragment.show(this, masterKeyId,
        +                        new Handler() {
        +                            @Override
        +                            public void handleMessage(Message message) {
        +                                if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
        +                                    mCurrentPassphrase = PassphraseCacheService.getCachedPassphrase(
        +                                            EditKeyActivity.this, masterKeyId);
        +                                    checkEmptyIDsWanted();
        +                                }
        +                            }
        +                        });
                         } else {
                             mCurrentPassphrase = passphrase;
                             checkEmptyIDsWanted();
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java
        index 01422ea13..470c85715 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java
        @@ -42,7 +42,6 @@ import org.sufficientlysecure.keychain.Id;
         import org.sufficientlysecure.keychain.R;
         import org.sufficientlysecure.keychain.helper.FileHelper;
         import org.sufficientlysecure.keychain.helper.Preferences;
        -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
         import org.sufficientlysecure.keychain.service.KeychainIntentService;
         import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
         import org.sufficientlysecure.keychain.service.PassphraseCacheService;
        @@ -256,7 +255,15 @@ public class EncryptFileFragment extends Fragment {
                     if (mEncryptInterface.getSignatureKey() != 0 &&
                         PassphraseCacheService.getCachedPassphrase(getActivity(),
                             mEncryptInterface.getSignatureKey()) == null) {
        -                showPassphraseDialog();
        +                PassphraseDialogFragment.show(getActivity(), mEncryptInterface.getSignatureKey(),
        +                    new Handler() {
        +                        @Override
        +                        public void handleMessage(Message message) {
        +                            if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
        +                                showOutputFileDialog();
        +                            }
        +                        }
        +                    });
         
                         return;
                     }
        @@ -370,34 +377,4 @@ public class EncryptFileFragment extends Fragment {
                     }
                 }
             }
        -
        -    /**
        -     * Shows passphrase dialog to cache a new passphrase the user enters for using it later for
        -     * encryption
        -     */
        -    private void showPassphraseDialog() {
        -        // Message is received after passphrase is cached
        -        Handler returnHandler = new Handler() {
        -            @Override
        -            public void handleMessage(Message message) {
        -                if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
        -                    showOutputFileDialog();
        -                }
        -            }
        -        };
        -
        -        // Create a new Messenger for the communication back
        -        Messenger messenger = new Messenger(returnHandler);
        -
        -        try {
        -            PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(
        -                    getActivity(), messenger, mEncryptInterface.getSignatureKey());
        -
        -            passphraseDialog.show(getActivity().getSupportFragmentManager(), "passphraseDialog");
        -        } catch (PgpGeneralException e) {
        -            Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
        -            // send message to handler to start encryption directly
        -            returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
        -        }
        -    }
         }
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java
        index a7818a1d8..ba11074fc 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java
        @@ -37,7 +37,6 @@ import org.sufficientlysecure.keychain.Constants;
         import org.sufficientlysecure.keychain.R;
         import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
         import org.sufficientlysecure.keychain.helper.Preferences;
        -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
         import org.sufficientlysecure.keychain.service.KeychainIntentService;
         import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
         import org.sufficientlysecure.keychain.service.PassphraseCacheService;
        @@ -121,7 +120,7 @@ public class EncryptMessageFragment extends Fragment {
                 return message;
             }
         
        -    private void encryptClicked(boolean toClipboard) {
        +    private void encryptClicked(final boolean toClipboard) {
                 if (mEncryptInterface.isModeSymmetric()) {
                     // symmetric encryption
         
        @@ -153,7 +152,15 @@ public class EncryptMessageFragment extends Fragment {
                     if (mEncryptInterface.getSignatureKey() != 0 &&
                         PassphraseCacheService.getCachedPassphrase(getActivity(),
                             mEncryptInterface.getSignatureKey()) == null) {
        -                showPassphraseDialog(toClipboard);
        +                PassphraseDialogFragment.show(getActivity(), mEncryptInterface.getSignatureKey(),
        +                    new Handler() {
        +                        @Override
        +                        public void handleMessage(Message message) {
        +                            if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
        +                                encryptStart(toClipboard);
        +                            }
        +                        }
        +                    });
         
                         return;
                     }
        @@ -249,35 +256,4 @@ public class EncryptMessageFragment extends Fragment {
                 // start service with intent
                 getActivity().startService(intent);
             }
        -
        -    /**
        -     * Shows passphrase dialog to cache a new passphrase the user enters for using it later for
        -     * encryption
        -     */
        -    private void showPassphraseDialog(final boolean toClipboard) {
        -        // Message is received after passphrase is cached
        -        Handler returnHandler = new Handler() {
        -            @Override
        -            public void handleMessage(Message message) {
        -                if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
        -                    encryptStart(toClipboard);
        -                }
        -            }
        -        };
        -
        -        // Create a new Messenger for the communication back
        -        Messenger messenger = new Messenger(returnHandler);
        -
        -        try {
        -            PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(
        -                    getActivity(), messenger, mEncryptInterface.getSignatureKey());
        -
        -            passphraseDialog.show(getActivity().getSupportFragmentManager(), "passphraseDialog");
        -        } catch (PgpGeneralException e) {
        -            Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
        -            // send message to handler to start encryption directly
        -            returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
        -        }
        -    }
        -
         }
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
        index b8db470b4..60dd98c18 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
        @@ -24,10 +24,12 @@ import android.content.Context;
         import android.content.DialogInterface;
         import android.content.DialogInterface.OnClickListener;
         import android.os.Bundle;
        +import android.os.Handler;
         import android.os.Message;
         import android.os.Messenger;
         import android.os.RemoteException;
         import android.support.v4.app.DialogFragment;
        +import android.support.v4.app.FragmentActivity;
         import android.view.KeyEvent;
         import android.view.LayoutInflater;
         import android.view.View;
        @@ -65,6 +67,27 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
             private EditText mPassphraseEditText;
             private boolean mCanKB;
         
        +    /**
        +     * Shows passphrase dialog to cache a new passphrase the user enters for using it later for
        +     * encryption. Based on mSecretKeyId it asks for a passphrase to open a private key or it asks
        +     * for a symmetric passphrase
        +     */
        +    public static void show(FragmentActivity context, long keyId, Handler returnHandler) {
        +        // Create a new Messenger for the communication back
        +        Messenger messenger = new Messenger(returnHandler);
        +
        +        try {
        +            PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(context,
        +                    messenger, keyId);
        +
        +            passphraseDialog.show(context.getSupportFragmentManager(), "passphraseDialog");
        +        } catch (PgpGeneralException e) {
        +            Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
        +            // send message to handler to start encryption directly
        +            returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
        +        }
        +    }
        +
             /**
              * Creates new instance of this dialog fragment
              *
        -- 
        cgit v1.2.3
        
        
        From d7c2488a0f08c8314706f76c22b53166309bcdf0 Mon Sep 17 00:00:00 2001
        From: Vincent Breitmoser 
        Date: Fri, 4 Apr 2014 18:49:45 +0200
        Subject: db-overhaul: fix key export (and some export-related ui changes)
        
        ---
         .../keychain/helper/ExportHelper.java              | 19 +++----
         .../keychain/service/KeychainIntentService.java    | 58 ++++++++++------------
         .../keychain/ui/EditKeyActivity.java               |  5 +-
         .../keychain/ui/KeyListActivity.java               | 15 ++----
         .../keychain/ui/KeyListFragment.java               | 23 ++++++---
         .../keychain/ui/ViewKeyActivity.java               | 11 ++--
         .../keychain/ui/ViewKeyMainFragment.java           | 16 ++++--
         7 files changed, 77 insertions(+), 70 deletions(-)
        
        (limited to 'OpenPGP-Keychain/src/main/java')
        
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java
        index 3040b4e9c..810f22d8e 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java
        @@ -61,8 +61,8 @@ public class ExportHelper {
             /**
              * Show dialog where to export keys
              */
        -    public void showExportKeysDialog(final long[] masterKeyIds, final int keyType,
        -                                     final String exportFilename, final String checkboxString) {
        +    public void showExportKeysDialog(final long[] masterKeyIds, final String exportFilename,
        +                                     final boolean showSecretCheckbox) {
                 mExportFilename = exportFilename;
         
                 // Message is received after file is selected
        @@ -71,14 +71,9 @@ public class ExportHelper {
                     public void handleMessage(Message message) {
                         if (message.what == FileDialogFragment.MESSAGE_OKAY) {
                             Bundle data = message.getData();
        -                    int type = keyType;
                             mExportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME);
         
        -                    if (data.getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED)) {
        -                        type = Id.type.public_secret_key;
        -                    }
        -
        -                    exportKeys(masterKeyIds, type);
        +                    exportKeys(masterKeyIds, data.getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED));
                         }
                     }
                 };
        @@ -98,9 +93,11 @@ public class ExportHelper {
                         }
         
                         String message = mActivity.getString(R.string.specify_file_to_export_to);
        +                String checkMsg = showSecretCheckbox ?
        +                        mActivity.getString(R.string.also_export_secret_keys) : null;
         
                         mFileDialog = FileDialogFragment.newInstance(messenger, title, message,
        -                        exportFilename, checkboxString);
        +                        exportFilename, checkMsg);
         
                         mFileDialog.show(mActivity.getSupportFragmentManager(), "fileDialog");
                     }
        @@ -110,7 +107,7 @@ public class ExportHelper {
             /**
              * Export keys
              */
        -    public void exportKeys(long[] masterKeyIds, int keyType) {
        +    public void exportKeys(long[] masterKeyIds, boolean exportSecret) {
                 Log.d(Constants.TAG, "exportKeys started");
         
                 // Send all information needed to service to export key in other thread
        @@ -122,7 +119,7 @@ public class ExportHelper {
                 Bundle data = new Bundle();
         
                 data.putString(KeychainIntentService.EXPORT_FILENAME, mExportFilename);
        -        data.putInt(KeychainIntentService.EXPORT_KEY_TYPE, keyType);
        +        data.putBoolean(KeychainIntentService.EXPORT_SECRET, exportSecret);
         
                 if (masterKeyIds == null) {
                     data.putBoolean(KeychainIntentService.EXPORT_ALL, true);
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
        index 768237c7d..1c6aa7971 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
        @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.service;
         
         import android.app.IntentService;
         import android.content.Intent;
        +import android.database.Cursor;
         import android.net.Uri;
         import android.os.Bundle;
         import android.os.Message;
        @@ -50,6 +51,8 @@ import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
         import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
         import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
         import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
        +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
        +import org.sufficientlysecure.keychain.provider.KeychainDatabase;
         import org.sufficientlysecure.keychain.provider.ProviderHelper;
         import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
         import org.sufficientlysecure.keychain.util.HkpKeyServer;
        @@ -147,7 +150,7 @@ public class KeychainIntentService extends IntentService
             // export key
             public static final String EXPORT_OUTPUT_STREAM = "export_output_stream";
             public static final String EXPORT_FILENAME = "export_filename";
        -    public static final String EXPORT_KEY_TYPE = "export_key_type";
        +    public static final String EXPORT_SECRET = "export_secret";
             public static final String EXPORT_ALL = "export_all";
             public static final String EXPORT_KEY_RING_MASTER_KEY_ID = "export_key_ring_id";
         
        @@ -635,19 +638,13 @@ public class KeychainIntentService extends IntentService
                 } else if (ACTION_EXPORT_KEYRING.equals(action)) {
                     try {
         
        -                /* Input */
        -                int keyType = Id.type.public_key;
        -                if (data.containsKey(EXPORT_KEY_TYPE)) {
        -                    keyType = data.getInt(EXPORT_KEY_TYPE);
        -                }
        +                boolean exportSecret = data.getBoolean(EXPORT_SECRET, false);
                         long[] masterKeyIds = data.getLongArray(EXPORT_KEY_RING_MASTER_KEY_ID);
                         String outputFile = data.getString(EXPORT_FILENAME);
         
                         // If not exporting all keys get the masterKeyIds of the keys to export from the intent
                         boolean exportAll = data.getBoolean(EXPORT_ALL);
         
        -                /* Operation */
        -
                         // check if storage is ready
                         if (!FileHelper.isStorageMounted(outputFile)) {
                             throw new PgpGeneralException(getString(R.string.error_external_storage_not_ready));
        @@ -655,31 +652,30 @@ public class KeychainIntentService extends IntentService
         
                         ArrayList publicMasterKeyIds = new ArrayList();
                         ArrayList secretMasterKeyIds = new ArrayList();
        -                // TODO redo
        -                ArrayList allPublicMasterKeyIds = null; // ProviderHelper.getPublicKeyRingsMasterKeyIds(this);
        -                ArrayList allSecretMasterKeyIds = null; // ProviderHelper.getSecretKeyRingsMasterKeyIds(this);
        -
        -                if (exportAll) {
        -                    // get all public key ring MasterKey ids
        -                    if (keyType == Id.type.public_key || keyType == Id.type.public_secret_key) {
        -                        publicMasterKeyIds = allPublicMasterKeyIds;
        -                    }
        -                    // get all secret key ring MasterKey ids
        -                    if (keyType == Id.type.secret_key || keyType == Id.type.public_secret_key) {
        -                        secretMasterKeyIds = allSecretMasterKeyIds;
        -                    }
        -                } else {
         
        -                    for (long masterKeyId : masterKeyIds) {
        -                        if ((keyType == Id.type.public_key || keyType == Id.type.public_secret_key)
        -                                && allPublicMasterKeyIds.contains(masterKeyId)) {
        -                            publicMasterKeyIds.add(masterKeyId);
        -                        }
        -                        if ((keyType == Id.type.secret_key || keyType == Id.type.public_secret_key)
        -                                && allSecretMasterKeyIds.contains(masterKeyId)) {
        -                            secretMasterKeyIds.add(masterKeyId);
        -                        }
        +                String selection = null;
        +                if(!exportAll) {
        +                    selection = KeychainDatabase.Tables.KEYS + "." + KeyRings.MASTER_KEY_ID + " IN( ";
        +                    for(long l : masterKeyIds) {
        +                        selection += Long.toString(l) + ",";
                             }
        +                    selection = selection.substring(0, selection.length()-1) + " )";
        +                }
        +
        +                Cursor cursor = getContentResolver().query(KeyRings.buildUnifiedKeyRingsUri(),
        +                        new String[]{ KeyRings.MASTER_KEY_ID, KeyRings.HAS_SECRET },
        +                        selection, null, null);
        +                try {
        +                    cursor.moveToFirst();
        +                    do {
        +                        // export public either way
        +                        publicMasterKeyIds.add(cursor.getLong(0));
        +                        // add secret if available (and requested)
        +                        if(exportSecret && cursor.getInt(1) != 0)
        +                            secretMasterKeyIds.add(cursor.getLong(0));
        +                    } while(cursor.moveToNext());
        +                } finally {
        +                    cursor.close();
                         }
         
                         PgpImportExport pgpImportExport = new PgpImportExport(this, this, this);
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
        index e6fd59d55..167401ac5 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
        @@ -339,9 +339,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
                             Toast.makeText(this, R.string.error_save_first, Toast.LENGTH_LONG).show();
                         } else {
                             long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri);
        -                long[] ids = new long[]{masterKeyId};
        -                mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC,
        -                        null);
        +                    mExportHelper.showExportKeysDialog(
        +                            new long[] { masterKeyId }, Constants.Path.APP_DIR_FILE_SEC, true);
                             return true;
                         }
                         return true;
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
        index 1f884d7e3..1bc6d4ee1 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
        @@ -23,7 +23,6 @@ import android.view.Menu;
         import android.view.MenuItem;
         
         import org.sufficientlysecure.keychain.Constants;
        -import org.sufficientlysecure.keychain.Id;
         import org.sufficientlysecure.keychain.R;
         import org.sufficientlysecure.keychain.helper.ExportHelper;
         
        @@ -55,26 +54,20 @@ public class KeyListActivity extends DrawerActivity {
                 switch (item.getItemId()) {
                     case R.id.menu_key_list_import:
                         callIntentForDrawerItem(Constants.DrawerItems.IMPORT_KEYS);
        -
                         return true;
        +
                     case R.id.menu_key_list_create:
                         createKey();
        -
                         return true;
        +
                     case R.id.menu_key_list_create_expert:
                         createKeyExpert();
        -
                         return true;
        -            case R.id.menu_key_list_export_public:
        -                mExportHelper.showExportKeysDialog(null,
        -                    Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB, null);
         
        +            case R.id.menu_key_list_export:
        +                mExportHelper.showExportKeysDialog(null, Constants.Path.APP_DIR_FILE_PUB, true);
                         return true;
        -            case R.id.menu_key_list_secret_export:
        -                mExportHelper.showExportKeysDialog(null, Id.type.secret_key,
        -                    Constants.Path.APP_DIR_FILE_SEC, null);
         
        -                return true;
                     default:
                         return super.onOptionsItemSelected(item);
                 }
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
        index 33ccd3a23..1d8f7c8ad 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
        @@ -60,7 +60,6 @@ import org.sufficientlysecure.keychain.helper.ExportHelper;
         import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
         import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
         import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
        -import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
         import org.sufficientlysecure.keychain.ui.adapter.HighlightQueryCursorAdapter;
         import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
         import org.sufficientlysecure.keychain.util.Log;
        @@ -68,7 +67,6 @@ import se.emilsjolander.stickylistheaders.ApiLevelTooLowException;
         import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
         import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
         
        -import java.util.ArrayList;
         import java.util.HashMap;
         
         /**
        @@ -194,10 +192,8 @@ public class KeyListFragment extends Fragment
                                 case R.id.menu_key_list_multi_export: {
                                     ids = mAdapter.getCurrentSelectedMasterKeyIds();
                                     ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity());
        -                            mExportHelper
        -                                    .showExportKeysDialog(ids, Id.type.public_key,
        -                                            Constants.Path.APP_DIR_FILE_PUB,
        -                                            getString(R.string.also_export_secret_keys));
        +                            mExportHelper.showExportKeysDialog(
        +                                    ids, Constants.Path.APP_DIR_FILE_PUB, mAdapter.isAnySecretSelected());
                                     break;
                                 }
                                 case R.id.menu_key_list_multi_select_all: {
        @@ -525,6 +521,13 @@ public class KeyListFragment extends Fragment
         
                 }
         
        +        public boolean isSecretAvailable(int id) {
        +            if (!mCursor.moveToPosition(id)) {
        +                throw new IllegalStateException("couldn't move cursor to position " + id);
        +            }
        +
        +            return mCursor.getInt(INDEX_HAS_SECRET) != 0;
        +        }
                 public long getMasterKeyId(int id) {
                     if (!mCursor.moveToPosition(id)) {
                         throw new IllegalStateException("couldn't move cursor to position " + id);
        @@ -633,6 +636,14 @@ public class KeyListFragment extends Fragment
                     notifyDataSetChanged();
                 }
         
        +        public boolean isAnySecretSelected() {
        +            for (int pos : mSelection.keySet()) {
        +                if(mAdapter.isSecretAvailable(pos))
        +                    return true;
        +            }
        +            return false;
        +        }
        +
                 public long[] getCurrentSelectedMasterKeyIds() {
                     long[] ids = new long[mSelection.size()];
                     int i = 0;
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        index af1fcfe52..7b9ba4b2d 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
        @@ -42,7 +42,6 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
         import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter;
         import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment;
         import org.sufficientlysecure.keychain.ui.dialog.ShareQrCodeDialogFragment;
        -import org.sufficientlysecure.keychain.util.Log;
         
         import java.util.ArrayList;
         
        @@ -120,10 +119,12 @@ public class ViewKeyActivity extends ActionBarActivity {
                         uploadToKeyserver(mDataUri);
                         return true;
                     case R.id.menu_key_view_export_file:
        -                long masterKeyId = Long.valueOf(mDataUri.getLastPathSegment());
        -                long[] ids = new long[]{masterKeyId};
        -                mExportHelper.showExportKeysDialog(ids, Id.type.public_key,
        -                        Constants.Path.APP_DIR_FILE_PUB, null);
        +                long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri);
        +                mExportHelper.showExportKeysDialog(
        +                        new long[] { masterKeyId } , Constants.Path.APP_DIR_FILE_PUB,
        +                        // TODO this doesn't work?
        +                        ((ViewKeyMainFragment) mTabsAdapter.getItem(0)).isSecretAvailable()
        +                );
                         return true;
                     case R.id.menu_key_view_share_default_fingerprint:
                         shareKey(mDataUri, true);
        diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        index 3c6ae514e..830c5fcae 100644
        --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
        @@ -81,6 +81,9 @@ public class ViewKeyMainFragment extends Fragment implements
         
             private Uri mDataUri;
         
        +    // for activity
        +    private boolean mSecretAvailable = false;
        +
             @Override
             public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                 View view = inflater.inflate(R.layout.view_key_main_fragment, container, false);
        @@ -227,9 +230,9 @@ public class ViewKeyMainFragment extends Fragment implements
                             mEmail.setText(mainUserId[1]);
                             mComment.setText(mainUserId[2]);
         
        -                    if (data.getInt(INDEX_UNIFIED_HAS_SECRET) > 0) {
        -                        // set this attribute. this is a LITTLE unclean, but we have the info available
        -                        // right here, so why not.
        +                    if (data.getInt(INDEX_UNIFIED_HAS_SECRET) != 0) {
        +                        mSecretAvailable = true;
        +
                                 mSecretKey.setTextColor(getResources().getColor(R.color.emphasis));
                                 mSecretKey.setText(R.string.secret_key_yes);
         
        @@ -244,6 +247,8 @@ public class ViewKeyMainFragment extends Fragment implements
                                     }
                                 });
                             } else {
        +                        mSecretAvailable = false;
        +
                                 mSecretKey.setTextColor(Color.BLACK);
                                 mSecretKey.setText(getResources().getString(R.string.secret_key_no));
         
        @@ -332,6 +337,11 @@ public class ViewKeyMainFragment extends Fragment implements
                 }
             }
         
        +    /** Returns true if the key current displayed is known to have a secret key. */
        +    public boolean isSecretAvailable() {
        +        return mSecretAvailable;
        +    }
        +
             private void encryptToContact(Uri dataUri) {
                 // TODO preselect from uri? should be feasible without trivial query
                 long keyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
        -- 
        cgit v1.2.3