From d097131a3dcdf806608f43e49e0be96cf34f5c64 Mon Sep 17 00:00:00 2001 From: Daniel Ramos Date: Tue, 14 Apr 2015 03:40:59 +0100 Subject: -Improved email sanity verifications when adding emails when creating a new Key -fixed a few NFC crashes -fixed a few instances when showing the keyboard would crash the Activity -fixed a case where adding new emails would crash the app if the user went back and forth between the Add Email fragment and the Add Name fragment. --- .../keychain/ui/CreateKeyEmailFragment.java | 95 ++++++++++++++++------ .../keychain/ui/base/BaseNfcActivity.java | 6 +- .../keychain/ui/dialog/AddEmailDialogFragment.java | 8 +- 3 files changed, 79 insertions(+), 30 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index 85e2f8e9d..26c307957 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -18,7 +18,6 @@ package org.sufficientlysecure.keychain.ui; import android.app.Activity; -import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -27,6 +26,7 @@ import android.support.v4.app.Fragment; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.util.Patterns; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -44,6 +44,7 @@ import org.sufficientlysecure.keychain.ui.widget.EmailEditText; import java.util.ArrayList; import java.util.List; +import java.util.regex.Pattern; public class CreateKeyEmailFragment extends Fragment { @@ -73,14 +74,13 @@ public class CreateKeyEmailFragment extends Fragment { * Checks if text of given EditText is not empty. If it is empty an error is * set and the EditText gets the focus. * - * @param context * @param editText * @return true if EditText is not empty */ - private static boolean isEditTextNotEmpty(Context context, EditText editText) { + private boolean isMainEmailValid(EditText editText) { boolean output = true; - if (editText.getText().length() == 0) { - editText.setError(context.getString(R.string.create_key_empty)); + if (!checkEmail(editText.getText().toString(), false)) { + editText.setError(getString(R.string.create_key_empty)); editText.requestFocus(); output = false; } else { @@ -125,7 +125,7 @@ public class CreateKeyEmailFragment extends Fragment { // initial values if (mAdditionalEmailModels == null) { mAdditionalEmailModels = new ArrayList<>(); - if (mCreateKeyActivity.mAdditionalEmails != null) { + if (mCreateKeyActivity.mAdditionalEmails != null && mEmailAdapter != null) { mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); } } @@ -144,6 +144,65 @@ public class CreateKeyEmailFragment extends Fragment { return view; } + /** + * Checks if a given email is valid + * + * @param email + * @param additionalEmail + * @return + */ + private boolean checkEmail(String email, boolean additionalEmail) { + //check for email format or if the user did any input + if (!isEmailFormatValid(email)) { + Notify.create(getActivity(), + getString(R.string.create_key_email_invalid_email), + Notify.LENGTH_LONG, Notify.Style.ERROR).show(); + return false; + } + + //check for duplicated emails + if (!additionalEmail && isEmailDuplicatedInsideAdapter(email) || additionalEmail && + mEmailEdit.getText().length() > 0 && email.equals(mEmailEdit.getText().toString())) { + Notify.create(getActivity(), + getString(R.string.create_key_email_already_exists_text), + Notify.LENGTH_LONG, Notify.Style.ERROR).show(); + return false; + } + + return true; + } + + /** + * Checks the email format + * Uses the default Android Email Pattern + * + * @param email + * @return + */ + private boolean isEmailFormatValid(String email) { + Pattern emailPattern = Patterns.EMAIL_ADDRESS; + + //check for email format or if the user did any input + return !(email.length() == 0 || !emailPattern.matcher(email).matches()); + } + + /** + * Checks for duplicated emails inside the additional email adapter. + * + * @param email + * @return + */ + private boolean isEmailDuplicatedInsideAdapter(String email) { + //check for duplicated emails inside the adapter + for (EmailAdapter.ViewModel model : mAdditionalEmailModels) { + if (email.equals(model.email)) { + return true; + } + } + + return false; + } + private void addEmail() { Handler returnHandler = new Handler() { @Override @@ -152,26 +211,10 @@ public class CreateKeyEmailFragment extends Fragment { Bundle data = message.getData(); String email = data.getString(AddEmailDialogFragment.MESSAGE_DATA_EMAIL); - - if (email.length() > 0 && mEmailEdit.getText().length() > 0 && - email.equals(mEmailEdit.getText().toString())) { - Notify.create(getActivity(), - getString(R.string.create_key_email_already_exists_text), - Notify.LENGTH_LONG, Notify.Style.ERROR).show(); - return; - } - //check for duplicated emails inside the adapter - for (EmailAdapter.ViewModel model : mAdditionalEmailModels) { - if (email.equals(model.email)) { - Notify.create(getActivity(), - getString(R.string.create_key_email_already_exists_text), - Notify.LENGTH_LONG, Notify.Style.ERROR).show(); - return; - } + if (checkEmail(email, true)) { + // add new user id + mEmailAdapter.add(email); } - - // add new user id - mEmailAdapter.add(email); } } }; @@ -191,7 +234,7 @@ public class CreateKeyEmailFragment extends Fragment { } private void nextClicked() { - if (isEditTextNotEmpty(getActivity(), mEmailEdit)) { + if (isMainEmailValid(mEmailEdit)) { // save state mCreateKeyActivity.mEmail = mEmailEdit.getText().toString(); mCreateKeyActivity.mAdditionalEmails = getAdditionalEmails(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java index 9b10ccdb1..4f6d5807e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java @@ -451,6 +451,8 @@ public abstract class BaseNfcActivity extends BaseActivity { */ public void enableNfcForegroundDispatch() { mNfcAdapter = NfcAdapter.getDefaultAdapter(this); + if(mNfcAdapter == null) return; + Intent nfcI = new Intent(this, getClass()) .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent nfcPendingIntent = PendingIntent.getActivity(this, 0, nfcI, PendingIntent.FLAG_CANCEL_CURRENT); @@ -472,7 +474,9 @@ public abstract class BaseNfcActivity extends BaseActivity { * Disable foreground dispatch in onPause! */ public void disableNfcForegroundDispatch() { - mNfcAdapter.disableForegroundDispatch(this); + if(mNfcAdapter != null) { + mNfcAdapter.disableForegroundDispatch(this); + } Log.d(Constants.TAG, "NfcForegroundDispatch has been disabled!"); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEmailDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEmailDialogFragment.java index 5d5ca533e..5b91b9d37 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEmailDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEmailDialogFragment.java @@ -112,9 +112,11 @@ public class AddEmailDialogFragment extends DialogFragment implements OnEditorAc mEmail.post(new Runnable() { @Override public void run() { - InputMethodManager imm = (InputMethodManager) getActivity() - .getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(mEmail, InputMethodManager.SHOW_IMPLICIT); + if(getActivity() != null) { + InputMethodManager imm = (InputMethodManager) getActivity() + .getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(mEmail, InputMethodManager.SHOW_IMPLICIT); + } } }); } -- cgit v1.2.3 From d9cabf8dc4a4de0153ab6a07919ae8d7614cfc9d Mon Sep 17 00:00:00 2001 From: Daniel Ramos Date: Fri, 24 Apr 2015 03:35:30 +0100 Subject: -Fixed a crash while recreating CreateKeyEmailFragment -Email data is properly restored while rotating the Activity. -Added necessary logic to guarantee that an email is actually valid before continuing, there are verifications for empty, duplicated and invalid formatted emails for both additional and main email. --- .../keychain/ui/CreateKeyEmailFragment.java | 32 +++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index 26c307957..8fdfb35cb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -47,16 +47,13 @@ import java.util.List; import java.util.regex.Pattern; public class CreateKeyEmailFragment extends Fragment { - - CreateKeyActivity mCreateKeyActivity; - EmailEditText mEmailEdit; - RecyclerView mEmailsRecyclerView; - View mBackButton; - View mNextButton; - - ArrayList mAdditionalEmailModels; - - EmailAdapter mEmailAdapter; + private CreateKeyActivity mCreateKeyActivity; + private EmailEditText mEmailEdit; + private RecyclerView mEmailsRecyclerView; + private View mBackButton; + private View mNextButton; + private ArrayList mAdditionalEmailModels; + private EmailAdapter mEmailAdapter; /** * Creates new instance of this fragment @@ -125,9 +122,6 @@ public class CreateKeyEmailFragment extends Fragment { // initial values if (mAdditionalEmailModels == null) { mAdditionalEmailModels = new ArrayList<>(); - if (mCreateKeyActivity.mAdditionalEmails != null && mEmailAdapter != null) { - mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); - } } if (mEmailAdapter == null) { @@ -137,6 +131,10 @@ public class CreateKeyEmailFragment extends Fragment { addEmail(); } }); + + if (mCreateKeyActivity.mAdditionalEmails != null) { + mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); + } } mEmailsRecyclerView.setAdapter(mEmailAdapter); @@ -203,6 +201,9 @@ public class CreateKeyEmailFragment extends Fragment { return false; } + /** + * Displays a dialog fragment for the user to input a valid email. + */ private void addEmail() { Handler returnHandler = new Handler() { @Override @@ -218,12 +219,11 @@ public class CreateKeyEmailFragment extends Fragment { } } }; - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); + Messenger messenger = new Messenger(returnHandler); AddEmailDialogFragment addEmailDialog = AddEmailDialogFragment.newInstance(messenger); - + addEmailDialog.setTargetFragment(this, -1); addEmailDialog.show(getActivity().getSupportFragmentManager(), "addEmailDialog"); } -- cgit v1.2.3 From ef52a3319a5931c46d5ae5e83f96c503782c805a Mon Sep 17 00:00:00 2001 From: Manoj Khanna Date: Fri, 24 Apr 2015 00:06:35 +0530 Subject: Espresso test for CreateKeyActivity --- .../keychain/ui/CreateKeyEmailFragment.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index 85e2f8e9d..ff0bf65be 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -125,9 +125,6 @@ public class CreateKeyEmailFragment extends Fragment { // initial values if (mAdditionalEmailModels == null) { mAdditionalEmailModels = new ArrayList<>(); - if (mCreateKeyActivity.mAdditionalEmails != null) { - mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); - } } if (mEmailAdapter == null) { @@ -137,6 +134,10 @@ public class CreateKeyEmailFragment extends Fragment { addEmail(); } }); + + if (mCreateKeyActivity.mAdditionalEmails != null) { + mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); + } } mEmailsRecyclerView.setAdapter(mEmailAdapter); @@ -157,7 +158,7 @@ public class CreateKeyEmailFragment extends Fragment { email.equals(mEmailEdit.getText().toString())) { Notify.create(getActivity(), getString(R.string.create_key_email_already_exists_text), - Notify.LENGTH_LONG, Notify.Style.ERROR).show(); + Notify.LENGTH_LONG, Notify.Style.ERROR).show(CreateKeyEmailFragment.this); return; } //check for duplicated emails inside the adapter @@ -165,7 +166,7 @@ public class CreateKeyEmailFragment extends Fragment { if (email.equals(model.email)) { Notify.create(getActivity(), getString(R.string.create_key_email_already_exists_text), - Notify.LENGTH_LONG, Notify.Style.ERROR).show(); + Notify.LENGTH_LONG, Notify.Style.ERROR).show(CreateKeyEmailFragment.this); return; } } -- cgit v1.2.3 From 4c74dbe11e39e5d227b661fd1ee9a08a74aebfc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 26 Apr 2015 01:28:29 +0200 Subject: UI fixes for Android < 5 --- .../sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java | 7 +++---- .../keychain/ui/CreateKeyPassphraseFragment.java | 8 ++------ .../java/org/sufficientlysecure/keychain/ui/MainActivity.java | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index 85e2f8e9d..3d7b31905 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -125,11 +125,7 @@ public class CreateKeyEmailFragment extends Fragment { // initial values if (mAdditionalEmailModels == null) { mAdditionalEmailModels = new ArrayList<>(); - if (mCreateKeyActivity.mAdditionalEmails != null) { - mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); - } } - if (mEmailAdapter == null) { mEmailAdapter = new EmailAdapter(mAdditionalEmailModels, new View.OnClickListener() { @Override @@ -138,6 +134,9 @@ public class CreateKeyEmailFragment extends Fragment { } }); } + if (mAdditionalEmailModels.isEmpty() && mCreateKeyActivity.mAdditionalEmails != null) { + mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); + } mEmailsRecyclerView.setAdapter(mEmailAdapter); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java index 32173edf7..3379e0a6d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java @@ -21,7 +21,6 @@ import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; -import android.text.Editable; import android.text.method.HideReturnsTransformationMethod; import android.text.method.PasswordTransformationMethod; import android.view.LayoutInflater; @@ -37,9 +36,6 @@ import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; import org.sufficientlysecure.keychain.ui.widget.PassphraseEditText; import org.sufficientlysecure.keychain.util.Passphrase; -import java.util.ArrayList; -import java.util.Arrays; - public class CreateKeyPassphraseFragment extends Fragment { // view @@ -111,8 +107,8 @@ public class CreateKeyPassphraseFragment extends Fragment { // initial values // TODO: using String here is unsafe... if (mCreateKeyActivity.mPassphrase != null) { - mPassphraseEdit.setText(Arrays.toString(mCreateKeyActivity.mPassphrase.getCharArray())); - mPassphraseEditAgain.setText(Arrays.toString(mCreateKeyActivity.mPassphrase.getCharArray())); + mPassphraseEdit.setText(new String(mCreateKeyActivity.mPassphrase.getCharArray())); + mPassphraseEditAgain.setText(new String(mCreateKeyActivity.mPassphrase.getCharArray())); } mPassphraseEdit.requestFocus(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java index 05cf64092..f571ba1e6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java @@ -64,7 +64,7 @@ public class MainActivity extends AppCompatActivity implements FabContainer { transaction.replace(R.id.main_fragment_container, mainFragment); transaction.commit(); - mToolbar = (Toolbar) findViewById(R.id.activity_main_toolbar); + mToolbar = (Toolbar) findViewById(R.id.toolbar); mToolbar.setTitle(R.string.app_name); setSupportActionBar(mToolbar); -- cgit v1.2.3 From 08d25f3685cffb7402bb6dd824bc0666bfe9a1c2 Mon Sep 17 00:00:00 2001 From: Daniel Ramos Date: Sun, 26 Apr 2015 18:56:37 +0100 Subject: -removed unneeded code from previous commits. I tested on a KitKat(4.4.2) and Lollipop (5.1) phone and everything seems to be preserved as expected. --- .../org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java | 3 --- 1 file changed, 3 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index ed4cf5b8a..473383e22 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -135,9 +135,6 @@ public class CreateKeyEmailFragment extends Fragment { mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); } } - if (mAdditionalEmailModels.isEmpty() && mCreateKeyActivity.mAdditionalEmails != null) { - mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); - } mEmailsRecyclerView.setAdapter(mEmailAdapter); -- cgit v1.2.3 From c0fbafde688f2f60f475121bf8c8b8ef2a59ce6d Mon Sep 17 00:00:00 2001 From: Daniel Ramos Date: Sun, 26 Apr 2015 19:11:51 +0100 Subject: -Removed unneeded view references from the fragment class since they are not used outside of createView. -cleanup --- .../sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index 473383e22..035945af3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -49,9 +49,6 @@ import java.util.regex.Pattern; public class CreateKeyEmailFragment extends Fragment { private CreateKeyActivity mCreateKeyActivity; private EmailEditText mEmailEdit; - private RecyclerView mEmailsRecyclerView; - private View mBackButton; - private View mNextButton; private ArrayList mAdditionalEmailModels; private EmailAdapter mEmailAdapter; @@ -92,9 +89,9 @@ public class CreateKeyEmailFragment extends Fragment { View view = inflater.inflate(R.layout.create_key_email_fragment, container, false); mEmailEdit = (EmailEditText) view.findViewById(R.id.create_key_email); - mBackButton = view.findViewById(R.id.create_key_back_button); - mNextButton = view.findViewById(R.id.create_key_next_button); - mEmailsRecyclerView = (RecyclerView) view.findViewById(R.id.create_key_emails); + View mBackButton = view.findViewById(R.id.create_key_back_button); + View mNextButton = view.findViewById(R.id.create_key_next_button); + RecyclerView mEmailsRecyclerView = (RecyclerView) view.findViewById(R.id.create_key_emails); // initial values mEmailEdit.setText(mCreateKeyActivity.mEmail); @@ -222,7 +219,6 @@ public class CreateKeyEmailFragment extends Fragment { Messenger messenger = new Messenger(returnHandler); AddEmailDialogFragment addEmailDialog = AddEmailDialogFragment.newInstance(messenger); - addEmailDialog.setTargetFragment(this, -1); addEmailDialog.show(getActivity().getSupportFragmentManager(), "addEmailDialog"); } -- cgit v1.2.3 From 8dbb82a8b61922e788e844e747b43f1838e6e58f Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 27 Apr 2015 13:51:39 +0200 Subject: profiling says: caching qrCode bitmaps is a good idea --- .../keychain/KeychainApplication.java | 14 +++++++ .../keychain/ui/util/QrCodeUtils.java | 48 +++++++++++++--------- 2 files changed, 43 insertions(+), 19 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index d26ccbe57..710dbf8aa 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -24,6 +24,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.res.Resources; +import android.graphics.Bitmap; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.Build; @@ -40,6 +41,8 @@ import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.TlsHelper; import java.security.Security; +import java.util.HashMap; + public class KeychainApplication extends Application { @@ -100,6 +103,17 @@ public class KeychainApplication extends Application { checkConsolidateRecovery(); } + public static HashMap qrCodeCache = new HashMap<>(); + + @Override + public void onTrimMemory(int level) { + super.onTrimMemory(level); + + if (level >= TRIM_MEMORY_UI_HIDDEN) { + qrCodeCache.clear(); + } + } + /** * Restart consolidate process if it has been interruped before */ diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java index b8d4ea7d2..5f71abdab 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java @@ -29,6 +29,7 @@ import com.google.zxing.qrcode.QRCodeWriter; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.KeychainApplication; import org.sufficientlysecure.keychain.util.Log; import java.util.Hashtable; @@ -40,36 +41,45 @@ public class QrCodeUtils { /** * Generate Bitmap with QR Code based on input. - * - * @param input - * @param size * @return QR Code as Bitmap */ public static Bitmap getQRCodeBitmap(final String input, final int size) { + try { - final Hashtable hints = new Hashtable<>(); - hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); - final BitMatrix result = new QRCodeWriter().encode(input, BarcodeFormat.QR_CODE, size, - size, hints); - - final int width = result.getWidth(); - final int height = result.getHeight(); - final int[] pixels = new int[width * height]; - - for (int y = 0; y < height; y++) { - final int offset = y * width; - for (int x = 0; x < width; x++) { - pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.TRANSPARENT; + + // the qrCodeCache is handled in KeychainApplication so we can + // properly react to onTrimMemory calls + Bitmap bitmap = KeychainApplication.qrCodeCache.get(input); + if (bitmap == null) { + + Hashtable hints = new Hashtable<>(); + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + BitMatrix result = new QRCodeWriter().encode(input, BarcodeFormat.QR_CODE, size, + size, hints); + + int width = result.getWidth(); + int height = result.getHeight(); + int[] pixels = new int[width * height]; + + for (int y = 0; y < height; y++) { + final int offset = y * width; + for (int x = 0; x < width; x++) { + pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.TRANSPARENT; + } } + + bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + bitmap.setPixels(pixels, 0, width, 0, 0, width, height); + + KeychainApplication.qrCodeCache.put(input, bitmap); } - final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - bitmap.setPixels(pixels, 0, width, 0, 0, width, height); return bitmap; - } catch (final WriterException e) { + } catch (WriterException e) { Log.e(Constants.TAG, "QrCodeUtils", e); return null; } + } } -- cgit v1.2.3 From 40834d1fcd2208bdaf3a2faff1184e168f3c2e3f Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 27 Apr 2015 14:40:52 +0200 Subject: add distinct status for messages signed by "your" key --- .../org/sufficientlysecure/keychain/ui/DecryptFragment.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index 651b56ab0..9c51893ce 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -231,6 +231,7 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements KeychainContract.KeyRings.IS_REVOKED, KeychainContract.KeyRings.IS_EXPIRED, KeychainContract.KeyRings.VERIFIED, + KeychainContract.KeyRings.HAS_ANY_SECRET, }; @SuppressWarnings("unused") @@ -239,6 +240,7 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements static final int INDEX_IS_REVOKED = 3; static final int INDEX_IS_EXPIRED = 4; static final int INDEX_VERIFIED = 5; + static final int INDEX_HAS_ANY_SECRET = 6; @Override public Loader onCreateLoader(int id, Bundle args) { @@ -283,6 +285,7 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements boolean isRevoked = data.getInt(INDEX_IS_REVOKED) != 0; boolean isExpired = data.getInt(INDEX_IS_EXPIRED) != 0; boolean isVerified = data.getInt(INDEX_VERIFIED) > 0; + boolean isYours = data.getInt(INDEX_HAS_ANY_SECRET) != 0; if (isRevoked) { mSignatureText.setText(R.string.decrypt_result_signature_revoked_key); @@ -302,6 +305,16 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements onVerifyLoaded(true); + } else if (isYours) { + + mSignatureText.setText(R.string.decrypt_result_signature_secret); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.VERIFIED); + + setSignatureLayoutVisibility(View.VISIBLE); + setShowAction(signatureKeyId); + + onVerifyLoaded(true); + } else if (isVerified) { mSignatureText.setText(R.string.decrypt_result_signature_certified); KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.VERIFIED); -- cgit v1.2.3 From 4ba2e4bcdd9c3b5f472b1502e55bcf753ee44b58 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 27 Apr 2015 17:45:50 +0200 Subject: display creation dates for ambiguous user ids --- .../keychain/ui/adapter/KeyAdapter.java | 21 ++++++++++++++++++++- .../ui/adapter/SelectKeyCursorAdapter.java | 22 +++++++++------------- 2 files changed, 29 insertions(+), 14 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java index 6f19fc6ed..f09dc1a4f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java @@ -27,6 +27,7 @@ import android.database.Cursor; import android.graphics.PorterDuff; import android.support.v4.widget.CursorAdapter; import android.text.format.DateFormat; +import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -88,6 +89,7 @@ public class KeyAdapter extends CursorAdapter { public Long mMasterKeyId; public TextView mMainUserId; public TextView mMainUserIdRest; + public TextView mCreationDate; public ImageView mStatus; public View mSlinger; public ImageButton mSlingerButton; @@ -98,6 +100,7 @@ public class KeyAdapter extends CursorAdapter { mStatus = (ImageView) view.findViewById(R.id.key_list_item_status_icon); mSlinger = view.findViewById(R.id.key_list_item_slinger_view); mSlingerButton = (ImageButton) view.findViewById(R.id.key_list_item_slinger_button); + mCreationDate = (TextView) view.findViewById(R.id.key_list_item_creation); } public void setData(Context context, Cursor cursor, Highlighter highlighter) { @@ -125,7 +128,7 @@ public class KeyAdapter extends CursorAdapter { boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0; boolean isExpired = cursor.getInt(INDEX_IS_EXPIRED) != 0; boolean isVerified = cursor.getInt(INDEX_VERIFIED) > 0; - // boolean hasDuplicate = cursor.getInt(INDEX_HAS_DUPLICATE_USER_ID) == 1; + boolean hasDuplicate = cursor.getInt(INDEX_HAS_DUPLICATE_USER_ID) != 0; mMasterKeyId = masterKeyId; @@ -165,6 +168,22 @@ public class KeyAdapter extends CursorAdapter { mMainUserId.setTextColor(context.getResources().getColor(R.color.black)); mMainUserIdRest.setTextColor(context.getResources().getColor(R.color.black)); } + + if (hasDuplicate) { + String dateTime = DateUtils.formatDateTime(context, + cursor.getLong(INDEX_CREATION) * 1000, + DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_SHOW_TIME + | DateUtils.FORMAT_SHOW_YEAR + | DateUtils.FORMAT_ABBREV_MONTH); + + mCreationDate.setText(context.getString(R.string.label_creation, + dateTime)); + mCreationDate.setVisibility(View.VISIBLE); + } else { + mCreationDate.setVisibility(View.GONE); + } + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java index 3308a4500..1ccb910d0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java @@ -20,7 +20,7 @@ package org.sufficientlysecure.keychain.ui.adapter; import android.content.Context; import android.database.Cursor; import android.support.v4.widget.CursorAdapter; -import android.text.format.DateFormat; +import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -36,10 +36,6 @@ import org.sufficientlysecure.keychain.ui.util.Highlighter; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; -import java.util.Calendar; -import java.util.Date; -import java.util.TimeZone; - /** * Yes this class is abstract! @@ -138,14 +134,14 @@ abstract public class SelectKeyCursorAdapter extends CursorAdapter { boolean duplicate = cursor.getLong(mIndexDuplicateUserId) > 0; if (duplicate) { - Date creationDate = new Date(cursor.getLong(mIndexCreation) * 1000); - Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - creationCal.setTime(creationDate); - // convert from UTC to time zone of device - creationCal.setTimeZone(TimeZone.getDefault()); - - h.creation.setText(context.getString(R.string.label_creation) + ": " - + DateFormat.getDateFormat(context).format(creationCal.getTime())); + String dateTime = DateUtils.formatDateTime(context, + cursor.getLong(mIndexCreation) * 1000, + DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_SHOW_TIME + | DateUtils.FORMAT_SHOW_YEAR + | DateUtils.FORMAT_ABBREV_MONTH); + + h.creation.setText(context.getString(R.string.label_creation, dateTime)); h.creation.setVisibility(View.VISIBLE); } else { h.creation.setVisibility(View.GONE); -- cgit v1.2.3 From 91b774d22334b91c1867b867c515d1fcd31e34da Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 27 Apr 2015 19:48:58 +0200 Subject: prevent crashes in EncryptKeyCompletionView --- .../keychain/ui/widget/EncryptKeyCompletionView.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java index 3d2e8b9df..4e691d962 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java @@ -110,7 +110,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView if (getContext() instanceof FragmentActivity) { mLoaderManager = ((FragmentActivity) getContext()).getSupportLoaderManager(); - mLoaderManager.initLoader(hashCode(), null, this); + mLoaderManager.initLoader(0, null, this); } else { Log.e(Constants.TAG, "EncryptKeyCompletionView must be attached to a FragmentActivity, this is " + getContext().getClass()); } @@ -154,6 +154,14 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView mAdapter.swapCursor(null); } + @Override + public void showDropDown() { + if (mAdapter.getCursor().isClosed()) { + return; + } + super.showDropDown(); + } + @Override public void onFocusChanged(boolean hasFocus, int direction, Rect previous) { super.onFocusChanged(hasFocus, direction, previous); @@ -171,7 +179,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView } Bundle args = new Bundle(); args.putString(ARG_QUERY, text.subSequence(start, end).toString()); - mLoaderManager.restartLoader(hashCode(), args, this); + mLoaderManager.restartLoader(0, args, this); } } -- cgit v1.2.3 From 871764219897d0105797fd59fe47fba41aba012b Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 28 Apr 2015 18:18:14 +0200 Subject: fix "select all" in key list multi-select --- .../main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 96ce101b5..1355bd3e6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -240,7 +240,7 @@ public class KeyListFragment extends LoaderFragment } case R.id.menu_key_list_multi_select_all: { // select all - for (int i = 0; i < mStickyList.getCount(); i++) { + for (int i = 0; i < mAdapter.getCount(); i++) { mStickyList.setItemChecked(i, true); } break; -- cgit v1.2.3 From cd55871950571035088823846739e04cac8ca432 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 28 Apr 2015 18:18:42 +0200 Subject: display unknown keys red rather than orange For an unknown key, there is no indication of the state the key is in. To indicate both immediate action required, and to make this status equal to its worst case (rather than *better* than its worst case), the status is displayed in red. At some point, we will probably want to download unknown keys automatically, at which point an unknown key will actually be an error state. This is an intermediate solution until then. --- .../org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java index ae66b59d4..91a7d361a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java @@ -475,7 +475,7 @@ public class KeyFormattingUtils { statusIcon.setImageDrawable( context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout_24dp)); if (color == KeyFormattingUtils.DEFAULT_COLOR) { - color = R.color.android_orange_light; + color = R.color.android_red_light; } statusIcon.setColorFilter(context.getResources().getColor(color), PorterDuff.Mode.SRC_IN); -- cgit v1.2.3 From 8ab49b076603ade77785a9bfb4a0f7a13bad483a Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 28 Apr 2015 18:21:51 +0200 Subject: fix crash when moving focus from EncryptKeyCompletionView with unknown text --- .../sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java index 4e691d962..525bc26ca 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java @@ -101,7 +101,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView /*if (completionText.startsWith("0x")) { }*/ - return null; + return ""; } @Override -- cgit v1.2.3 From e159e619d299c0e91f3f9527186e50649657dd73 Mon Sep 17 00:00:00 2001 From: Daniel Ramos Date: Thu, 30 Apr 2015 00:44:01 +0100 Subject: -removed unneeded inputType attribute from xml files (+1 squashed commits) Squashed commits: [ef54e68] -code style fixing --- .../keychain/ui/CreateKeyEmailFragment.java | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index 035945af3..078135772 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -89,9 +89,9 @@ public class CreateKeyEmailFragment extends Fragment { View view = inflater.inflate(R.layout.create_key_email_fragment, container, false); mEmailEdit = (EmailEditText) view.findViewById(R.id.create_key_email); - View mBackButton = view.findViewById(R.id.create_key_back_button); - View mNextButton = view.findViewById(R.id.create_key_next_button); - RecyclerView mEmailsRecyclerView = (RecyclerView) view.findViewById(R.id.create_key_emails); + View backButton = view.findViewById(R.id.create_key_back_button); + View nextButton = view.findViewById(R.id.create_key_next_button); + RecyclerView emailsRecyclerView = (RecyclerView) view.findViewById(R.id.create_key_emails); // initial values mEmailEdit.setText(mCreateKeyActivity.mEmail); @@ -100,21 +100,21 @@ public class CreateKeyEmailFragment extends Fragment { if (mCreateKeyActivity.mEmail == null) { mEmailEdit.requestFocus(); } - mBackButton.setOnClickListener(new View.OnClickListener() { + backButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mCreateKeyActivity.loadFragment(null, FragAction.TO_LEFT); } }); - mNextButton.setOnClickListener(new View.OnClickListener() { + nextButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { nextClicked(); } }); - mEmailsRecyclerView.setHasFixedSize(true); - mEmailsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); - mEmailsRecyclerView.setItemAnimator(new DefaultItemAnimator()); + emailsRecyclerView.setHasFixedSize(true); + emailsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); + emailsRecyclerView.setItemAnimator(new DefaultItemAnimator()); // initial values if (mAdditionalEmailModels == null) { @@ -133,7 +133,7 @@ public class CreateKeyEmailFragment extends Fragment { } } - mEmailsRecyclerView.setAdapter(mEmailAdapter); + emailsRecyclerView.setAdapter(mEmailAdapter); return view; } @@ -216,7 +216,7 @@ public class CreateKeyEmailFragment extends Fragment { } }; // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); + Messenger messenger = new Messenger(returnHandler); AddEmailDialogFragment addEmailDialog = AddEmailDialogFragment.newInstance(messenger); addEmailDialog.show(getActivity().getSupportFragmentManager(), "addEmailDialog"); -- cgit v1.2.3 From 7c275fed9d93e0c45b2fb00d94bde702b44c8811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 30 Apr 2015 18:45:43 +0200 Subject: API: Allow selection of decryption keys when decryption fails --- .../keychain/remote/OpenPgpService.java | 34 ++++-- .../keychain/remote/ui/RemoteServiceActivity.java | 1 + .../remote/ui/SelectAllowedKeysActivity.java | 115 +++++++++++++++++++++ 3 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectAllowedKeysActivity.java (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index c51edf59c..badc3c131 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -34,6 +34,7 @@ import org.openintents.openpgp.util.OpenPgpApi; import org.spongycastle.bcpg.CompressionAlgorithmTags; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel; import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult; import org.sufficientlysecure.keychain.pgp.PgpConstants; @@ -47,6 +48,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity; +import org.sufficientlysecure.keychain.remote.ui.SelectAllowedKeysActivity; import org.sufficientlysecure.keychain.remote.ui.SelectSignKeyIdActivity; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; @@ -205,6 +207,18 @@ public class OpenPgpService extends RemoteService { PendingIntent.FLAG_CANCEL_CURRENT); } + private PendingIntent getSelectAllowedKeysIntent(Intent data) { + // If signature is unknown we return an _additional_ PendingIntent + // to retrieve the missing key + Intent intent = new Intent(getBaseContext(), SelectAllowedKeysActivity.class); + intent.putExtra(SelectAllowedKeysActivity.EXTRA_SERVICE_INTENT, data); + intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(getCurrentCallingPackage())); + + return PendingIntent.getActivity(getBaseContext(), 0, + intent, + PendingIntent.FLAG_CANCEL_CURRENT); + } + private PendingIntent getShowKeyPendingIntent(long masterKeyId) { Intent intent = new Intent(getBaseContext(), ViewKeyActivity.class); intent.setData(KeyRings.buildGenericKeyRingUri(masterKeyId)); @@ -476,13 +490,12 @@ public class OpenPgpService extends RemoteService { } String currentPkg = getCurrentCallingPackage(); - Set allowedKeyIds; + Set allowedKeyIds = mProviderHelper.getAllowedKeyIdsForApp( + KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg)); + if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 7) { - allowedKeyIds = mProviderHelper.getAllKeyIdsForApp( - ApiAccounts.buildBaseUri(currentPkg)); - } else { - allowedKeyIds = mProviderHelper.getAllowedKeyIdsForApp( - KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg)); + allowedKeyIds.addAll(mProviderHelper.getAllKeyIdsForApp( + ApiAccounts.buildBaseUri(currentPkg))); } long inputLength = is.available(); @@ -575,6 +588,15 @@ public class OpenPgpService extends RemoteService { return result; } else { LogEntryParcel errorMsg = pgpResult.getLog().getLast(); + + if (errorMsg.mType == OperationResult.LogType.MSG_DC_ERROR_NO_KEY) { + // allow user to select allowed keys + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_INTENT, getSelectAllowedKeysIntent(data)); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); + return result; + } + throw new Exception(getString(errorMsg.mType.getMsgId())); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java index f312c0d44..5facde64f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java @@ -45,6 +45,7 @@ import org.sufficientlysecure.keychain.util.Log; import java.util.ArrayList; +// TODO: make extensible BaseRemoteServiceActivity and extend these cases from it public class RemoteServiceActivity extends BaseActivity { public static final String ACTION_REGISTER = Constants.INTENT_PREFIX + "API_ACTIVITY_REGISTER"; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectAllowedKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectAllowedKeysActivity.java new file mode 100644 index 000000000..767106ff0 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectAllowedKeysActivity.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2015 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.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.ui.base.BaseActivity; +import org.sufficientlysecure.keychain.util.Log; + +public class SelectAllowedKeysActivity extends BaseActivity { + + public static final String EXTRA_SERVICE_INTENT = "data"; + + private Uri mAppUri; + + private AppSettingsAllowedKeysListFragment mAllowedKeysFragment; + + Intent mServiceData; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Inflate a "Done" custom action bar + setFullScreenDialogDoneClose(R.string.api_settings_save, + new View.OnClickListener() { + @Override + public void onClick(View v) { + save(); + } + }, + new View.OnClickListener() { + @Override + public void onClick(View v) { + cancel(); + } + }); + + Intent intent = getIntent(); + mServiceData = intent.getParcelableExtra(EXTRA_SERVICE_INTENT); + 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(savedInstanceState, mAppUri); + } + } + + @Override + protected void initLayout() { + setContentView(R.layout.api_remote_select_allowed_keys); + } + + private void save() { + mAllowedKeysFragment.saveAllowedKeys(); + setResult(Activity.RESULT_OK, mServiceData); + finish(); + } + + private void cancel() { + setResult(Activity.RESULT_CANCELED); + finish(); + } + + private void loadData(Bundle savedInstanceState, Uri appUri) { + Uri allowedKeysUri = appUri.buildUpon().appendPath(KeychainContract.PATH_ALLOWED_KEYS).build(); + Log.d(Constants.TAG, "allowedKeysUri: " + allowedKeysUri); + startListFragments(savedInstanceState, allowedKeysUri); + } + + private void startListFragments(Bundle savedInstanceState, Uri allowedKeysUri) { + // 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 fragments + mAllowedKeysFragment = AppSettingsAllowedKeysListFragment.newInstance(allowedKeysUri); + // Add the fragment to the 'fragment_container' FrameLayout + // NOTE: We use commitAllowingStateLoss() to prevent weird crashes! + getSupportFragmentManager().beginTransaction() + .replace(R.id.api_allowed_keys_list_fragment, mAllowedKeysFragment) + .commitAllowingStateLoss(); + // do it immediately! + getSupportFragmentManager().executePendingTransactions(); + } + +} -- cgit v1.2.3 From c88d2e42b747fac700ab6ac47beeae91c76bdbd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 30 Apr 2015 18:57:51 +0200 Subject: Fix key creation string and display --- .../keychain/ui/adapter/KeyAdapter.java | 17 +---------------- .../keychain/ui/adapter/SelectKeyCursorAdapter.java | 2 +- .../keychain/ui/widget/KeySpinner.java | 16 ++++++++-------- 3 files changed, 10 insertions(+), 25 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java index f09dc1a4f..eef44a94b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java @@ -173,11 +173,10 @@ public class KeyAdapter extends CursorAdapter { String dateTime = DateUtils.formatDateTime(context, cursor.getLong(INDEX_CREATION) * 1000, DateUtils.FORMAT_SHOW_DATE - | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_ABBREV_MONTH); - mCreationDate.setText(context.getString(R.string.label_creation, + mCreationDate.setText(context.getString(R.string.label_key_created, dateTime)); mCreationDate.setVisibility(View.VISIBLE); } else { @@ -281,20 +280,6 @@ public class KeyAdapter extends CursorAdapter { } } - public boolean hasDuplicate() { - return mHasDuplicate; - } - - public String getCreationDate(Context context) { - Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - creationCal.setTime(mCreation); - // convert from UTC to time zone of device - creationCal.setTimeZone(TimeZone.getDefault()); - - return context.getString(R.string.label_creation) + ": " - + DateFormat.getDateFormat(context).format(creationCal.getTime()); - } - } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java index 1ccb910d0..68c59f647 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java @@ -141,7 +141,7 @@ abstract public class SelectKeyCursorAdapter extends CursorAdapter { | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_ABBREV_MONTH); - h.creation.setText(context.getString(R.string.label_creation, dateTime)); + h.creation.setText(context.getString(R.string.label_key_created, dateTime)); h.creation.setVisibility(View.VISIBLE); } else { h.creation.setVisibility(View.GONE); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java index fc5ecd76a..aecc81604 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java @@ -26,6 +26,7 @@ import android.support.v4.content.Loader; import android.support.v4.widget.CursorAdapter; import android.support.v7.widget.AppCompatSpinner; import android.text.format.DateFormat; +import android.text.format.DateUtils; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; @@ -167,14 +168,13 @@ public abstract class KeySpinner extends AppCompatSpinner implements LoaderManag boolean duplicate = cursor.getLong(mIndexDuplicate) > 0; if (duplicate) { - Date creationDate = new Date(cursor.getLong(mIndexCreationDate) * 1000); - Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - creationCal.setTime(creationDate); - // convert from UTC to time zone of device - creationCal.setTimeZone(TimeZone.getDefault()); - - vDuplicate.setText(context.getString(R.string.label_creation) + ": " - + DateFormat.getDateFormat(context).format(creationCal.getTime())); + String dateTime = DateUtils.formatDateTime(context, + cursor.getLong(mIndexCreationDate) * 1000, + DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_SHOW_YEAR + | DateUtils.FORMAT_ABBREV_MONTH); + + vDuplicate.setText(context.getString(R.string.label_key_created, dateTime)); vDuplicate.setVisibility(View.VISIBLE); } else { vDuplicate.setVisibility(View.GONE); -- cgit v1.2.3 From 5ad50b99a21642e466cad0d9e23976793f7cf765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 30 Apr 2015 19:02:33 +0200 Subject: Remove time from key creation display --- .../sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java index 68c59f647..a6cb52977 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java @@ -137,7 +137,6 @@ abstract public class SelectKeyCursorAdapter extends CursorAdapter { String dateTime = DateUtils.formatDateTime(context, cursor.getLong(mIndexCreation) * 1000, DateUtils.FORMAT_SHOW_DATE - | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_ABBREV_MONTH); -- cgit v1.2.3 From e91dc022fbd5d616c2ac1b5bbd47a693b9f8f8d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 1 May 2015 14:36:22 +0200 Subject: Fix nullpointer in EncryptKeyCompletionView --- .../keychain/ui/widget/EncryptKeyCompletionView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java index 525bc26ca..df6b82978 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java @@ -136,7 +136,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView where += " AND " + KeyRings.USER_ID + " LIKE ?"; return new CursorLoader(getContext(), baseUri, KeyAdapter.PROJECTION, where, - new String[] { "%" + query + "%" }, null); + new String[]{"%" + query + "%"}, null); } mAdapter.setSearchQuery(null); @@ -156,7 +156,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView @Override public void showDropDown() { - if (mAdapter.getCursor().isClosed()) { + if (mAdapter == null || mAdapter.getCursor().isClosed()) { return; } super.showDropDown(); -- cgit v1.2.3 From f3870cee290a7f8f996c14d457cba3be4127cd3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 1 May 2015 14:44:40 +0200 Subject: More nullpointer fixes --- .../sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java index df6b82978..63a1aade9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java @@ -156,7 +156,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView @Override public void showDropDown() { - if (mAdapter == null || mAdapter.getCursor().isClosed()) { + if (mAdapter == null || mAdapter.getCursor() == null || mAdapter.getCursor().isClosed()) { return; } super.showDropDown(); -- cgit v1.2.3 From 4e425495e6d69cbe54840f926e659eb12e79eefe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 4 May 2015 13:57:43 +0200 Subject: Apply patch from https://github.com/open-keychain/open-keychain/issues/1240 with db upgrade --- .../provider/TemporaryStorageProvider.java | 30 ++++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java index a65d222da..6dd4a1633 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java @@ -31,10 +31,12 @@ import android.provider.OpenableColumns; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.util.DatabaseUtil; +import org.sufficientlysecure.keychain.util.Log; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.util.UUID; public class TemporaryStorageProvider extends ContentProvider { @@ -44,7 +46,7 @@ public class TemporaryStorageProvider extends ContentProvider { private static final String COLUMN_NAME = "name"; private static final String COLUMN_TIME = "time"; private static final Uri BASE_URI = Uri.parse("content://org.sufficientlysecure.keychain.tempstorage/"); - private static final int DB_VERSION = 1; + private static final int DB_VERSION = 2; public static Uri createFile(Context context, String targetName) { ContentValues contentValues = new ContentValues(); @@ -66,7 +68,7 @@ public class TemporaryStorageProvider extends ContentProvider { @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_FILES + " (" + - COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + + COLUMN_ID + " TEXT PRIMARY KEY, " + COLUMN_NAME + " TEXT, " + COLUMN_TIME + " INTEGER" + ");"); @@ -74,7 +76,17 @@ public class TemporaryStorageProvider extends ContentProvider { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - + Log.d(Constants.TAG, "Upgrading files db from " + oldVersion + " to " + newVersion); + + switch (oldVersion) { + case 1: + db.execSQL("DROP TABLE IF EXISTS files"); + db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_FILES + " (" + + COLUMN_ID + " TEXT PRIMARY KEY, " + + COLUMN_NAME + " TEXT, " + + COLUMN_TIME + " INTEGER" + + ");"); + } } } @@ -82,13 +94,13 @@ public class TemporaryStorageProvider extends ContentProvider { private File getFile(Uri uri) throws FileNotFoundException { try { - return getFile(Integer.parseInt(uri.getLastPathSegment())); + return getFile(uri.getLastPathSegment()); } catch (NumberFormatException e) { throw new FileNotFoundException(); } } - private File getFile(int id) { + private File getFile(String id) { return new File(getContext().getCacheDir(), "temp/" + id); } @@ -133,13 +145,15 @@ public class TemporaryStorageProvider extends ContentProvider { if (!values.containsKey(COLUMN_TIME)) { values.put(COLUMN_TIME, System.currentTimeMillis()); } + String uuid = UUID.randomUUID().toString(); + values.put(COLUMN_ID, uuid); int insert = (int) db.getWritableDatabase().insert(TABLE_FILES, null, values); try { - getFile(insert).createNewFile(); + getFile(uuid).createNewFile(); } catch (IOException e) { return null; } - return Uri.withAppendedPath(BASE_URI, Long.toString(insert)); + return Uri.withAppendedPath(BASE_URI, uuid); } @Override @@ -152,7 +166,7 @@ public class TemporaryStorageProvider extends ContentProvider { selectionArgs, null, null, null); if (files != null) { while (files.moveToNext()) { - getFile(files.getInt(0)).delete(); + getFile(files.getString(0)).delete(); } files.close(); return db.getWritableDatabase().delete(TABLE_FILES, selection, selectionArgs); -- cgit v1.2.3 From 51bb96742f95b5b3b1ce68aef76fb5b0ddc5575d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 4 May 2015 14:01:34 +0200 Subject: Apply patch from https://github.com/open-keychain/open-keychain/issues/1222#issuecomment-98582938 --- .../keychain/pgp/PgpSignEncryptOperation.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java index 8ecb30cdd..9073e81b9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java @@ -178,13 +178,20 @@ public class PgpSignEncryptOperation extends BaseOperation { case PIN: case PATTERN: case PASSPHRASE: { - if (cryptoInput.getPassphrase() == null) { + Passphrase localPassphrase = cryptoInput.getPassphrase(); + if (localPassphrase == null) { + try { + localPassphrase = getCachedPassphrase(signingKeyRing.getMasterKeyId(), signingKey.getKeyId()); + } catch (PassphraseCacheInterface.NoSecretKeyException ignored) { + } + } + if (localPassphrase == null) { log.add(LogType.MSG_PSE_PENDING_PASSPHRASE, indent + 1); return new PgpSignEncryptResult(log, RequiredInputParcel.createRequiredSignPassphrase( signingKeyRing.getMasterKeyId(), signingKey.getKeyId(), cryptoInput.getSignatureTime())); } - if (!signingKey.unlock(cryptoInput.getPassphrase())) { + if (!signingKey.unlock(localPassphrase)) { log.add(LogType.MSG_PSE_ERROR_BAD_PASSPHRASE, indent); return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); } -- cgit v1.2.3 From b726dea244f020660d5260d3211d6500655fe680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 4 May 2015 14:12:42 +0200 Subject: license header for PgpCertifyOperation --- .../keychain/pgp/PgpCertifyOperation.java | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java index 90ec3053f..bf2349734 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * Copyright (C) 2015 Vincent Breitmoser + * + * 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.pgp; @@ -32,7 +50,7 @@ public class PgpCertifyOperation { OperationLog log, int indent, CertifyAction action, - Map signedHashes, + Map signedHashes, Date creationTimestamp) { if (!secretKey.isMasterKey()) { -- cgit v1.2.3 From dedda1603c73b66276931dacf8a7c5d1798db4a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 4 May 2015 14:19:16 +0200 Subject: Fix dublicated code in CreateKeyEmailFragment --- .../org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java | 4 ---- 1 file changed, 4 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index f338a53a6..552fe6954 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -133,10 +133,6 @@ public class CreateKeyEmailFragment extends Fragment { addEmail(); } }); - - if (mCreateKeyActivity.mAdditionalEmails != null) { - mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); - } } if (mAdditionalEmailModels.isEmpty() && mCreateKeyActivity.mAdditionalEmails != null) { mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); -- cgit v1.2.3 From e1ca612bc43475e8a0d6a289c978d226a9ab78c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 4 May 2015 14:55:56 +0200 Subject: Use more simple email validation regex --- .../keychain/ui/CreateKeyEmailFragment.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index aeae8a1ad..0a9ddf382 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -26,7 +26,6 @@ import android.support.v4.app.Fragment; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.util.Patterns; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -52,6 +51,10 @@ public class CreateKeyEmailFragment extends Fragment { private ArrayList mAdditionalEmailModels; private EmailAdapter mEmailAdapter; + // NOTE: Do not use more complicated pattern like defined in android.util.Patterns.EMAIL_ADDRESS + // EMAIL_ADDRESS fails for mails with umlauts for example + private static final Pattern EMAIL_PATTERN = Pattern.compile(".[\\S]+@.[\\S]+\\.[a-z]+"); + /** * Creates new instance of this fragment */ @@ -146,7 +149,7 @@ public class CreateKeyEmailFragment extends Fragment { * @return */ private boolean checkEmail(String email, boolean additionalEmail) { - //check for email format or if the user did any input + // check for email format or if the user did any input if (!isEmailFormatValid(email)) { Notify.create(getActivity(), getString(R.string.create_key_email_invalid_email), @@ -154,7 +157,7 @@ public class CreateKeyEmailFragment extends Fragment { return false; } - //check for duplicated emails + // check for duplicated emails if (!additionalEmail && isEmailDuplicatedInsideAdapter(email) || additionalEmail && mEmailEdit.getText().length() > 0 && email.equals(mEmailEdit.getText().toString())) { Notify.create(getActivity(), @@ -174,10 +177,8 @@ public class CreateKeyEmailFragment extends Fragment { * @return */ private boolean isEmailFormatValid(String email) { - Pattern emailPattern = Patterns.EMAIL_ADDRESS; - - //check for email format or if the user did any input - return !(email.length() == 0 || !emailPattern.matcher(email).matches()); + // check for email format or if the user did any input + return !(email.length() == 0 || !EMAIL_PATTERN.matcher(email).matches()); } /** -- cgit v1.2.3 From 2cd1cf9192aee76a0f2481281148783519d208a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 4 May 2015 15:27:19 +0200 Subject: Fix email pattern --- .../java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index 0a9ddf382..64dc71785 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -53,7 +53,7 @@ public class CreateKeyEmailFragment extends Fragment { // NOTE: Do not use more complicated pattern like defined in android.util.Patterns.EMAIL_ADDRESS // EMAIL_ADDRESS fails for mails with umlauts for example - private static final Pattern EMAIL_PATTERN = Pattern.compile(".[\\S]+@.[\\S]+\\.[a-z]+"); + private static final Pattern EMAIL_PATTERN = Pattern.compile("^[\\S]+@[\\S]+\\.[a-z]+$"); /** * Creates new instance of this fragment -- cgit v1.2.3 From f3090f2939ede5db92afbd5fd52e9a509556a15f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 4 May 2015 15:34:48 +0200 Subject: Display notify above keyboard in CreateKeyEmailFragment --- .../org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index 64dc71785..dbff4fb9f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -153,7 +153,7 @@ public class CreateKeyEmailFragment extends Fragment { if (!isEmailFormatValid(email)) { Notify.create(getActivity(), getString(R.string.create_key_email_invalid_email), - Notify.LENGTH_LONG, Notify.Style.ERROR).show(); + Notify.LENGTH_LONG, Notify.Style.ERROR).show(CreateKeyEmailFragment.this); return false; } @@ -162,7 +162,7 @@ public class CreateKeyEmailFragment extends Fragment { mEmailEdit.getText().length() > 0 && email.equals(mEmailEdit.getText().toString())) { Notify.create(getActivity(), getString(R.string.create_key_email_already_exists_text), - Notify.LENGTH_LONG, Notify.Style.ERROR).show(); + Notify.LENGTH_LONG, Notify.Style.ERROR).show(CreateKeyEmailFragment.this); return false; } -- cgit v1.2.3 From 2583f77f07708b388043991c0dd6c9ef1d14f523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 4 May 2015 20:47:19 +0200 Subject: Fix cancel/skip in create key wizard --- .../keychain/ui/CreateKeyActivity.java | 2 +- .../keychain/ui/CreateKeyStartFragment.java | 83 +++++++++------------- .../keychain/ui/CreateKeyYubiKeyWaitFragment.java | 58 +++++++++++++++ .../keychain/ui/CreateKeyYubiWaitFragment.java | 58 --------------- 4 files changed, 92 insertions(+), 109 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyWaitFragment.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiWaitFragment.java (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java index 0b203614b..dfb94ebb9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java @@ -99,7 +99,7 @@ public class CreateKeyActivity extends BaseNfcActivity { if (mFirstTime) { setTitle(R.string.app_name); - setActionBarIcon(R.drawable.ic_launcher); + mToolbar.setNavigationIcon(null); mToolbar.setNavigationOnClickListener(null); } else { setTitle(R.string.title_manage_my_keys); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyStartFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyStartFragment.java index 3f56949f5..1a844e6e4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyStartFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyStartFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014-2015 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 @@ -18,37 +18,20 @@ package org.sufficientlysecure.keychain.ui; import android.app.Activity; -import android.content.Context; 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.support.v7.widget.DefaultItemAnimator; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ImageButton; import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; -import org.sufficientlysecure.keychain.ui.dialog.AddEmailDialogFragment; -import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; -import org.sufficientlysecure.keychain.ui.widget.EmailEditText; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Preferences; -import java.util.ArrayList; -import java.util.List; - public class CreateKeyStartFragment extends Fragment { CreateKeyActivity mCreateKeyActivity; @@ -56,8 +39,8 @@ public class CreateKeyStartFragment extends Fragment { View mCreateKey; View mImportKey; View mYubiKey; - TextView mCancel; - public static final int REQUEST_CODE_CREATE_OR_IMPORT_KEY = 0x00007012; + TextView mSkipOrCancel; + public static final int REQUEST_CODE_IMPORT_KEY = 0x00007012; /** * Creates new instance of this fragment @@ -79,12 +62,12 @@ public class CreateKeyStartFragment extends Fragment { mCreateKey = view.findViewById(R.id.create_key_create_key_button); mImportKey = view.findViewById(R.id.create_key_import_button); mYubiKey = view.findViewById(R.id.create_key_yubikey_button); - mCancel = (TextView) view.findViewById(R.id.create_key_cancel); + mSkipOrCancel = (TextView) view.findViewById(R.id.create_key_cancel); if (mCreateKeyActivity.mFirstTime) { - mCancel.setText(R.string.first_time_skip); + mSkipOrCancel.setText(R.string.first_time_skip); } else { - mCancel.setText(R.string.btn_do_not_save); + mSkipOrCancel.setText(R.string.btn_do_not_save); } mCreateKey.setOnClickListener(new View.OnClickListener() { @@ -98,7 +81,7 @@ public class CreateKeyStartFragment extends Fragment { mYubiKey.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - CreateKeyYubiWaitFragment frag = new CreateKeyYubiWaitFragment(); + CreateKeyYubiKeyWaitFragment frag = new CreateKeyYubiKeyWaitFragment(); mCreateKeyActivity.loadFragment(frag, FragAction.TO_RIGHT); } }); @@ -108,48 +91,48 @@ public class CreateKeyStartFragment extends Fragment { public void onClick(View v) { Intent intent = new Intent(mCreateKeyActivity, ImportKeysActivity.class); intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN); - startActivityForResult(intent, REQUEST_CODE_CREATE_OR_IMPORT_KEY); + startActivityForResult(intent, REQUEST_CODE_IMPORT_KEY); } }); - mCancel.setOnClickListener(new View.OnClickListener() { + mSkipOrCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - finishSetup(null); + if (mCreateKeyActivity.mFirstTime) { + Preferences prefs = Preferences.getPreferences(mCreateKeyActivity); + prefs.setFirstTime(false); + Intent intent = new Intent(mCreateKeyActivity, MainActivity.class); + startActivity(intent); + mCreateKeyActivity.finish(); + } else { + // just finish activity and return data + mCreateKeyActivity.setResult(Activity.RESULT_CANCELED); + mCreateKeyActivity.finish(); + } } }); return view; } - - private void finishSetup(Intent srcData) { - if (mCreateKeyActivity.mFirstTime) { - Preferences prefs = Preferences.getPreferences(mCreateKeyActivity); - prefs.setFirstTime(false); - } - Intent intent = new Intent(mCreateKeyActivity, MainActivity.class); - // give intent through to display notify - if (srcData != null) { - intent.putExtras(srcData); - } - startActivity(intent); - mCreateKeyActivity.finish(); - } - - // workaround for https://code.google.com/p/android/issues/detail?id=61394 -// @Override -// public boolean onKeyDown(int keyCode, KeyEvent event) { -// return keyCode == KeyEvent.KEYCODE_MENU || super.onKeyDown(keyCode, event); -// } - @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode == REQUEST_CODE_CREATE_OR_IMPORT_KEY) { + if (requestCode == REQUEST_CODE_IMPORT_KEY) { if (resultCode == Activity.RESULT_OK) { - finishSetup(data); + if (mCreateKeyActivity.mFirstTime) { + Preferences prefs = Preferences.getPreferences(mCreateKeyActivity); + prefs.setFirstTime(false); + Intent intent = new Intent(mCreateKeyActivity, MainActivity.class); + intent.putExtras(data); + startActivity(intent); + mCreateKeyActivity.finish(); + } else { + // just finish activity and return data + mCreateKeyActivity.setResult(Activity.RESULT_OK, data); + mCreateKeyActivity.finish(); + } } } else { Log.e(Constants.TAG, "No valid request code!"); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyWaitFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyWaitFragment.java new file mode 100644 index 000000000..0b8586c0a --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyWaitFragment.java @@ -0,0 +1,58 @@ +/* + * 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.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; + + +public class CreateKeyYubiKeyWaitFragment extends Fragment { + + CreateKeyActivity mCreateKeyActivity; + View mBackButton; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.create_yubikey_wait_fragment, container, false); + + mBackButton = view.findViewById(R.id.create_key_back_button); + + mBackButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mCreateKeyActivity.loadFragment(null, FragAction.TO_LEFT); + } + }); + + return view; + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + mCreateKeyActivity = (CreateKeyActivity) getActivity(); + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiWaitFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiWaitFragment.java deleted file mode 100644 index 579dddf79..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiWaitFragment.java +++ /dev/null @@ -1,58 +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; - -import android.app.Activity; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; - - -public class CreateKeyYubiWaitFragment extends Fragment { - - CreateKeyActivity mCreateKeyActivity; - View mBackButton; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.create_yubikey_wait_fragment, container, false); - - mBackButton = view.findViewById(R.id.create_key_back_button); - - mBackButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mCreateKeyActivity.loadFragment(null, FragAction.TO_LEFT); - } - }); - - return view; - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - mCreateKeyActivity = (CreateKeyActivity) getActivity(); - } - -} -- cgit v1.2.3 From 291f95db5ad2028ef252448e47b4ad22a297bf33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 4 May 2015 21:13:07 +0200 Subject: Fix revoked/expired state in decrypt activity --- .../keychain/ui/DecryptFilesFragment.java | 2 +- .../keychain/ui/DecryptFragment.java | 26 ++++++------------- .../keychain/ui/DecryptTextFragment.java | 30 +++++++++++----------- 3 files changed, 24 insertions(+), 34 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java index 6c1902af1..e5ddcbbd6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java @@ -309,7 +309,7 @@ public class DecryptFilesFragment extends DecryptFragment { } @Override - protected void onVerifyLoaded(boolean verified) { + protected void onVerifyLoaded(boolean hideErrorOverlay) { } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index 9c51893ce..230f478ae 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -55,7 +55,6 @@ import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.util.Preferences; - public abstract class DecryptFragment extends CryptoOperationFragment implements LoaderManager.LoaderCallbacks { @@ -91,7 +90,6 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements mSignatureName = (TextView) getActivity().findViewById(R.id.result_signature_name); mSignatureEmail = (TextView) getActivity().findViewById(R.id.result_signature_email); mSignatureAction = (TextView) getActivity().findViewById(R.id.result_signature_action); - } private void lookupUnknownKey(long unknownKeyId) { @@ -113,12 +111,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements final ImportKeyResult result = returnData.getParcelable(OperationResult.EXTRA_RESULT); - // if (!result.success()) { - result.createNotify(getActivity()).show(); - // } + result.createNotify(getActivity()).show(); getLoaderManager().restartLoader(LOADER_ID_UNIFIED, null, DecryptFragment.this); - } } }; @@ -153,7 +148,6 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); getActivity().startService(intent); - } private void showKey(long keyId) { @@ -205,7 +199,6 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements } getLoaderManager().restartLoader(LOADER_ID_UNIFIED, null, this); - } private void setSignatureLayoutVisibility(int visibility) { @@ -228,8 +221,6 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements KeychainContract.KeyRings._ID, KeychainContract.KeyRings.MASTER_KEY_ID, KeychainContract.KeyRings.USER_ID, - KeychainContract.KeyRings.IS_REVOKED, - KeychainContract.KeyRings.IS_EXPIRED, KeychainContract.KeyRings.VERIFIED, KeychainContract.KeyRings.HAS_ANY_SECRET, }; @@ -237,10 +228,8 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements @SuppressWarnings("unused") 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_IS_EXPIRED = 4; - static final int INDEX_VERIFIED = 5; - static final int INDEX_HAS_ANY_SECRET = 6; + static final int INDEX_VERIFIED = 3; + static final int INDEX_HAS_ANY_SECRET = 4; @Override public Loader onCreateLoader(int id, Bundle args) { @@ -282,8 +271,10 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements getActivity(), mSignatureResult.getKeyId())); } - boolean isRevoked = data.getInt(INDEX_IS_REVOKED) != 0; - boolean isExpired = data.getInt(INDEX_IS_EXPIRED) != 0; + // NOTE: Don't use revoked and expired fields from database, they don't show + // revoked/expired subkeys + boolean isRevoked = mSignatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED; + boolean isExpired = mSignatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED; boolean isVerified = data.getInt(INDEX_VERIFIED) > 0; boolean isYours = data.getInt(INDEX_HAS_ANY_SECRET) != 0; @@ -344,7 +335,6 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements } setSignatureLayoutVisibility(View.GONE); - } private void showUnknownKeyStatus() { @@ -407,6 +397,6 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements } - protected abstract void onVerifyLoaded(boolean verified); + protected abstract void onVerifyLoaded(boolean hideErrorOverlay); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java index 6f576a112..b8f1aee63 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java @@ -50,8 +50,8 @@ public class DecryptTextFragment extends DecryptFragment { public static final String ARG_CIPHERTEXT = "ciphertext"; // view - private LinearLayout mValidLayout; - private LinearLayout mInvalidLayout; + private LinearLayout mContentLayout; + private LinearLayout mErrorOverlayLayout; private TextView mText; // model @@ -78,16 +78,16 @@ public class DecryptTextFragment extends DecryptFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.decrypt_text_fragment, container, false); - mValidLayout = (LinearLayout) view.findViewById(R.id.decrypt_text_valid); - mInvalidLayout = (LinearLayout) view.findViewById(R.id.decrypt_text_invalid); + mContentLayout = (LinearLayout) view.findViewById(R.id.decrypt_content); + mErrorOverlayLayout = (LinearLayout) view.findViewById(R.id.decrypt_error_overlay); mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext); - Button vInvalidButton = (Button) view.findViewById(R.id.decrypt_text_invalid_button); - vInvalidButton.setOnClickListener(new View.OnClickListener() { + Button vErrorOverlayButton = (Button) view.findViewById(R.id.decrypt_error_overlay_button); + vErrorOverlayButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mInvalidLayout.setVisibility(View.GONE); - mValidLayout.setVisibility(View.VISIBLE); + mErrorOverlayLayout.setVisibility(View.GONE); + mContentLayout.setVisibility(View.VISIBLE); } }); @@ -244,17 +244,17 @@ public class DecryptTextFragment extends DecryptFragment { } @Override - protected void onVerifyLoaded(boolean verified) { + protected void onVerifyLoaded(boolean hideErrorOverlay) { - mShowMenuOptions = verified; + mShowMenuOptions = hideErrorOverlay; getActivity().supportInvalidateOptionsMenu(); - if (verified) { - mInvalidLayout.setVisibility(View.GONE); - mValidLayout.setVisibility(View.VISIBLE); + if (hideErrorOverlay) { + mErrorOverlayLayout.setVisibility(View.GONE); + mContentLayout.setVisibility(View.VISIBLE); } else { - mInvalidLayout.setVisibility(View.VISIBLE); - mValidLayout.setVisibility(View.GONE); + mErrorOverlayLayout.setVisibility(View.VISIBLE); + mContentLayout.setVisibility(View.GONE); } } -- cgit v1.2.3 From b06e7cd737c9f85c37fb2d17533cc1a2b25715a9 Mon Sep 17 00:00:00 2001 From: William Faulk Date: Wed, 29 Apr 2015 19:59:32 -0400 Subject: Fix Bluetooth share without breaking others --- .../keychain/KeychainApplication.java | 13 +++++ .../keychain/ui/ViewKeyAdvShareFragment.java | 65 ++++++++++++++++++++-- .../keychain/ui/util/KeyFormattingUtils.java | 30 +++++++++- 3 files changed, 99 insertions(+), 9 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index 710dbf8aa..161979ce3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -40,6 +40,8 @@ import org.sufficientlysecure.keychain.util.PRNGFixes; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.TlsHelper; +import java.io.File; +import java.io.FilenameFilter; import java.security.Security; import java.util.HashMap; @@ -88,6 +90,17 @@ public class KeychainApplication extends Application { } } + // Clean up leftover Bluetooth Share files + for (File toDelete : this.getExternalCacheDir().listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String filename) { + if (filename.matches("^key-[0-9a-fA-F]{8}\\.pgp\\.asc$")) { + return true; + } + return false; + } + })) { toDelete.delete(); } + brandGlowEffect(getApplicationContext(), getApplicationContext().getResources().getColor(R.color.primary)); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java index 6bd3a9303..4141da202 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java @@ -26,6 +26,7 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.os.FileObserver; import android.support.v4.app.ActivityCompat; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; @@ -54,6 +55,9 @@ import org.sufficientlysecure.keychain.ui.util.QrCodeUtils; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.NfcHelper; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; import java.io.IOException; @@ -175,11 +179,11 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements boolean toClipboard) { try { String content; + byte[] fingerprintData = (byte[]) providerHelper.getGenericData( + KeyRings.buildUnifiedKeyRingUri(dataUri), + Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB); if (fingerprintOnly) { - byte[] data = (byte[]) providerHelper.getGenericData( - KeyRings.buildUnifiedKeyRingUri(dataUri), - Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB); - String fingerprint = KeyFormattingUtils.convertFingerprintToHex(data); + String fingerprint = KeyFormattingUtils.convertFingerprintToHex(fingerprintData); if (!toClipboard) { content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint; } else { @@ -213,13 +217,62 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements Intent sendIntent = new Intent(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, content); sendIntent.setType("text/plain"); + String title; if (fingerprintOnly) { title = getResources().getString(R.string.title_share_fingerprint_with); } else { title = getResources().getString(R.string.title_share_key); } - startActivity(Intent.createChooser(sendIntent, title)); + Intent shareChooser = Intent.createChooser(sendIntent, title); + + // Bluetooth Share will convert text/plain sent via EXTRA_TEXT to HTML + // Add replacement extra to send a text/plain file instead. + try { + final File contentFile = new File(getActivity().getExternalCacheDir(), + "key-" + KeyFormattingUtils.getShortKeyIdAsHexFromFingerprint(fingerprintData, false) + + ".pgp.asc"); + FileWriter contentFileWriter = new FileWriter(contentFile, false); + BufferedWriter contentWriter = new BufferedWriter(contentFileWriter); + contentWriter.write(content); + contentWriter.close(); + Uri contentUri = Uri.fromFile(contentFile); + + final Runnable deleteContentFile = new Runnable() { + public void run() { + contentFile.delete(); + } + }; + + // delete the file after Bluetooth Share closes the file + FileObserver tempFileObserver = new FileObserver(contentFile.getAbsolutePath(), + FileObserver.CLOSE_NOWRITE) { + @Override + public void onEvent(int event, String path) { + // Hopefully it will only be opened and then closed by the share process once + getContainer().post(deleteContentFile); + } + }; + tempFileObserver.startWatching(); + + // If it's not complete in 1m, the file was not used; delete it + getContainer().postDelayed(deleteContentFile, 1 * 60 * 1000); + + // create replacement extras inside try{}: + // if file creation fails, just don't add the replacements + Bundle replacements = new Bundle(); + shareChooser.putExtra(Intent.EXTRA_REPLACEMENT_EXTRAS, replacements); + + Bundle bluetoothExtra = new Bundle(sendIntent.getExtras()); + replacements.putBundle("com.android.bluetooth", bluetoothExtra); + + bluetoothExtra.putParcelable(Intent.EXTRA_STREAM, contentUri); + } catch (IOException e) { + Log.e(Constants.TAG, "error creating temporary Bluetooth key share file!", e); + Notify.create(getActivity(), R.string.error_bluetooth_file, Notify.Style.ERROR).show(); + } + + startActivity(shareChooser); } } catch (PgpGeneralException | IOException e) { Log.e(Constants.TAG, "error processing key!", e); @@ -379,4 +432,4 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements } -} \ No newline at end of file +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java index 91a7d361a..0b80b5fe9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java @@ -227,6 +227,14 @@ public class KeyFormattingUtils { return buf.getLong(); } + public static int getShortKeyIdFromFingerprint(byte[] fingerprint) { + ByteBuffer buf = ByteBuffer.wrap(fingerprint); + // skip first 16 bytes of the fingerprint + buf.position(16); + // the last four bytes are the short key id (big endian, which is default order in ByteBuffer) + return buf.getInt(); + } + /** * Convert key id from long to 64 bit hex string *

@@ -238,16 +246,24 @@ public class KeyFormattingUtils { * @return */ public static String convertKeyIdToHex(long keyId) { + return convertKeyIdToHex(keyId, true); + } + + public static String convertKeyIdToHex(long keyId, boolean header) { long upper = keyId >> 32; if (upper == 0) { // this is a short key id - return convertKeyIdToHexShort(keyId); + return convertKeyIdToHexShort(keyId, header); } - return "0x" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId); + return header?"0x":"" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId); } public static String convertKeyIdToHexShort(long keyId) { - return "0x" + convertKeyIdToHex32bit(keyId); + return convertKeyIdToHexShort(keyId, true); + } + + public static String convertKeyIdToHexShort(long keyId, boolean header) { + return header?"0x":"" + convertKeyIdToHex32bit(keyId); } private static String convertKeyIdToHex32bit(long keyId) { @@ -258,6 +274,14 @@ public class KeyFormattingUtils { return hexString; } + public static String getKeyIdAsHexFromFingerprint(byte[] fingerprint, boolean header) { + return convertKeyIdToHex(getKeyIdFromFingerprint(fingerprint), header); + } + + public static String getShortKeyIdAsHexFromFingerprint(byte[] fingerprint, boolean header) { + return convertKeyIdToHex(getShortKeyIdFromFingerprint(fingerprint), header); + } + /** * Makes a human-readable version of a key ID, which is usually 64 bits: lower-case, no * leading 0x, space-separated quartets (for keys whose length in hex is divisible by 4) -- cgit v1.2.3 From 6383d19dd3921220633686e0e8e78d2d961e0aad Mon Sep 17 00:00:00 2001 From: William Faulk Date: Thu, 30 Apr 2015 18:48:25 -0400 Subject: Wrap EXTRA_REPLACEMENT_EXTRAS section so it only runs on Lollipop or greater --- .../keychain/ui/ViewKeyAdvShareFragment.java | 86 +++++++++++----------- 1 file changed, 44 insertions(+), 42 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java index 4141da202..81720d816 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java @@ -228,48 +228,50 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements // Bluetooth Share will convert text/plain sent via EXTRA_TEXT to HTML // Add replacement extra to send a text/plain file instead. - try { - final File contentFile = new File(getActivity().getExternalCacheDir(), - "key-" + KeyFormattingUtils.getShortKeyIdAsHexFromFingerprint(fingerprintData, false) + - ".pgp.asc"); - FileWriter contentFileWriter = new FileWriter(contentFile, false); - BufferedWriter contentWriter = new BufferedWriter(contentFileWriter); - contentWriter.write(content); - contentWriter.close(); - Uri contentUri = Uri.fromFile(contentFile); - - final Runnable deleteContentFile = new Runnable() { - public void run() { - contentFile.delete(); - } - }; - - // delete the file after Bluetooth Share closes the file - FileObserver tempFileObserver = new FileObserver(contentFile.getAbsolutePath(), - FileObserver.CLOSE_NOWRITE) { - @Override - public void onEvent(int event, String path) { - // Hopefully it will only be opened and then closed by the share process once - getContainer().post(deleteContentFile); - } - }; - tempFileObserver.startWatching(); - - // If it's not complete in 1m, the file was not used; delete it - getContainer().postDelayed(deleteContentFile, 1 * 60 * 1000); - - // create replacement extras inside try{}: - // if file creation fails, just don't add the replacements - Bundle replacements = new Bundle(); - shareChooser.putExtra(Intent.EXTRA_REPLACEMENT_EXTRAS, replacements); - - Bundle bluetoothExtra = new Bundle(sendIntent.getExtras()); - replacements.putBundle("com.android.bluetooth", bluetoothExtra); - - bluetoothExtra.putParcelable(Intent.EXTRA_STREAM, contentUri); - } catch (IOException e) { - Log.e(Constants.TAG, "error creating temporary Bluetooth key share file!", e); - Notify.create(getActivity(), R.string.error_bluetooth_file, Notify.Style.ERROR).show(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + try { + final File contentFile = new File(getActivity().getExternalCacheDir(), + "key-" + KeyFormattingUtils.getShortKeyIdAsHexFromFingerprint(fingerprintData, false) + + ".pgp.asc"); + FileWriter contentFileWriter = new FileWriter(contentFile, false); + BufferedWriter contentWriter = new BufferedWriter(contentFileWriter); + contentWriter.write(content); + contentWriter.close(); + Uri contentUri = Uri.fromFile(contentFile); + + final Runnable deleteContentFile = new Runnable() { + public void run() { + contentFile.delete(); + } + }; + + // delete the file after Bluetooth Share closes the file + FileObserver tempFileObserver = new FileObserver(contentFile.getAbsolutePath(), + FileObserver.CLOSE_NOWRITE) { + @Override + public void onEvent(int event, String path) { + // Hopefully it will only be opened and then closed by the share process once + getContainer().post(deleteContentFile); + } + }; + tempFileObserver.startWatching(); + + // If it's not complete in 1m, the file was not used; delete it + getContainer().postDelayed(deleteContentFile, 1 * 60 * 1000); + + // create replacement extras inside try{}: + // if file creation fails, just don't add the replacements + Bundle replacements = new Bundle(); + shareChooser.putExtra(Intent.EXTRA_REPLACEMENT_EXTRAS, replacements); + + Bundle bluetoothExtra = new Bundle(sendIntent.getExtras()); + replacements.putBundle("com.android.bluetooth", bluetoothExtra); + + bluetoothExtra.putParcelable(Intent.EXTRA_STREAM, contentUri); + } catch (IOException e) { + Log.e(Constants.TAG, "error creating temporary Bluetooth key share file!", e); + Notify.create(getActivity(), R.string.error_bluetooth_file, Notify.Style.ERROR).show(); + } } startActivity(shareChooser); -- cgit v1.2.3 From be3e52884f363de83fd058db1e99e55866413ba4 Mon Sep 17 00:00:00 2001 From: William Faulk Date: Mon, 4 May 2015 12:17:06 -0400 Subject: Use primary user ID for filename instead of short key ID --- .../sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java index 81720d816..bbca45479 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java @@ -43,6 +43,8 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; +import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; +import org.sufficientlysecure.keychain.pgp.UncachedPublicKey; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeychainContract; @@ -230,9 +232,10 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements // Add replacement extra to send a text/plain file instead. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { try { + String primaryUserId = UncachedKeyRing.decodeFromData(content.getBytes()). + getPublicKey().getPrimaryUserIdWithFallback(); final File contentFile = new File(getActivity().getExternalCacheDir(), - "key-" + KeyFormattingUtils.getShortKeyIdAsHexFromFingerprint(fingerprintData, false) + - ".pgp.asc"); + primaryUserId + ".pgp.asc"); FileWriter contentFileWriter = new FileWriter(contentFile, false); BufferedWriter contentWriter = new BufferedWriter(contentFileWriter); contentWriter.write(content); -- cgit v1.2.3 From af1809eebc1ce9caf8de4a23a6ecfc919890e59b Mon Sep 17 00:00:00 2001 From: William Faulk Date: Mon, 4 May 2015 13:58:20 -0400 Subject: Use FILE_EXTENSION constants --- .../org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java index bbca45479..6fc2de335 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java @@ -235,7 +235,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements String primaryUserId = UncachedKeyRing.decodeFromData(content.getBytes()). getPublicKey().getPrimaryUserIdWithFallback(); final File contentFile = new File(getActivity().getExternalCacheDir(), - primaryUserId + ".pgp.asc"); + primaryUserId + Constants.FILE_EXTENSION_PGP_ALTERNATE + Constants.FILE_EXTENSION_ASC); FileWriter contentFileWriter = new FileWriter(contentFile, false); BufferedWriter contentWriter = new BufferedWriter(contentFileWriter); contentWriter.write(content); -- cgit v1.2.3 From eabc6cd8d45858a5ceaa44270078aba380b69e12 Mon Sep 17 00:00:00 2001 From: William Faulk Date: Mon, 4 May 2015 16:35:05 -0400 Subject: use TemporaryStorageProvider for Bluetooth Share --- .../provider/TemporaryStorageProvider.java | 9 +++-- .../keychain/ui/ViewKeyAdvShareFragment.java | 41 +++++++--------------- 2 files changed, 18 insertions(+), 32 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java index 6dd4a1633..45f806960 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java @@ -48,6 +48,8 @@ public class TemporaryStorageProvider extends ContentProvider { private static final Uri BASE_URI = Uri.parse("content://org.sufficientlysecure.keychain.tempstorage/"); private static final int DB_VERSION = 2; + private static File cacheDir; + public static Uri createFile(Context context, String targetName) { ContentValues contentValues = new ContentValues(); contentValues.put(COLUMN_NAME, targetName); @@ -90,7 +92,7 @@ public class TemporaryStorageProvider extends ContentProvider { } } - private TemporaryStorageDatabase db; + private static TemporaryStorageDatabase db; private File getFile(Uri uri) throws FileNotFoundException { try { @@ -101,13 +103,14 @@ public class TemporaryStorageProvider extends ContentProvider { } private File getFile(String id) { - return new File(getContext().getCacheDir(), "temp/" + id); + return new File(cacheDir, "temp/" + id); } @Override public boolean onCreate() { db = new TemporaryStorageDatabase(getContext()); - return new File(getContext().getCacheDir(), "temp").mkdirs(); + cacheDir = getContext().getCacheDir(); + return new File(cacheDir, "temp").mkdirs(); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java index 6fc2de335..17aca2373 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java @@ -26,7 +26,7 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; -import android.os.FileObserver; +import android.os.ParcelFileDescriptor; import android.support.v4.app.ActivityCompat; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; @@ -44,13 +44,13 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; -import org.sufficientlysecure.keychain.pgp.UncachedPublicKey; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; 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.ProviderHelper; +import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.QrCodeUtils; @@ -58,9 +58,9 @@ import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.NfcHelper; import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; +import java.io.OutputStreamWriter; import java.io.IOException; +import java.io.FileNotFoundException; public class ViewKeyAdvShareFragment extends LoaderFragment implements @@ -234,33 +234,16 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements try { String primaryUserId = UncachedKeyRing.decodeFromData(content.getBytes()). getPublicKey().getPrimaryUserIdWithFallback(); - final File contentFile = new File(getActivity().getExternalCacheDir(), + + TemporaryStorageProvider shareFileProv = new TemporaryStorageProvider(); + Uri contentUri = TemporaryStorageProvider.createFile(getActivity(), primaryUserId + Constants.FILE_EXTENSION_PGP_ALTERNATE + Constants.FILE_EXTENSION_ASC); - FileWriter contentFileWriter = new FileWriter(contentFile, false); - BufferedWriter contentWriter = new BufferedWriter(contentFileWriter); + + BufferedWriter contentWriter = new BufferedWriter(new OutputStreamWriter( + new ParcelFileDescriptor.AutoCloseOutputStream( + shareFileProv.openFile(contentUri, "w")))); contentWriter.write(content); contentWriter.close(); - Uri contentUri = Uri.fromFile(contentFile); - - final Runnable deleteContentFile = new Runnable() { - public void run() { - contentFile.delete(); - } - }; - - // delete the file after Bluetooth Share closes the file - FileObserver tempFileObserver = new FileObserver(contentFile.getAbsolutePath(), - FileObserver.CLOSE_NOWRITE) { - @Override - public void onEvent(int event, String path) { - // Hopefully it will only be opened and then closed by the share process once - getContainer().post(deleteContentFile); - } - }; - tempFileObserver.startWatching(); - - // If it's not complete in 1m, the file was not used; delete it - getContainer().postDelayed(deleteContentFile, 1 * 60 * 1000); // create replacement extras inside try{}: // if file creation fails, just don't add the replacements @@ -271,7 +254,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements replacements.putBundle("com.android.bluetooth", bluetoothExtra); bluetoothExtra.putParcelable(Intent.EXTRA_STREAM, contentUri); - } catch (IOException e) { + } catch (FileNotFoundException e) { Log.e(Constants.TAG, "error creating temporary Bluetooth key share file!", e); Notify.create(getActivity(), R.string.error_bluetooth_file, Notify.Style.ERROR).show(); } -- cgit v1.2.3 From 44b47e185d351718f105d7247c727c5f4d6bd0a4 Mon Sep 17 00:00:00 2001 From: William Faulk Date: Mon, 4 May 2015 17:09:59 -0400 Subject: use single file extension --- .../org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java index 17aca2373..fde0f62fd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java @@ -237,7 +237,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements TemporaryStorageProvider shareFileProv = new TemporaryStorageProvider(); Uri contentUri = TemporaryStorageProvider.createFile(getActivity(), - primaryUserId + Constants.FILE_EXTENSION_PGP_ALTERNATE + Constants.FILE_EXTENSION_ASC); + primaryUserId + Constants.FILE_EXTENSION_ASC); BufferedWriter contentWriter = new BufferedWriter(new OutputStreamWriter( new ParcelFileDescriptor.AutoCloseOutputStream( -- cgit v1.2.3 From 7e7892ff2ee6c49e6971483b759337dd216a96b7 Mon Sep 17 00:00:00 2001 From: William Faulk Date: Mon, 4 May 2015 17:15:10 -0400 Subject: revert unneeded changes for old temp Bluetooth share file --- .../sufficientlysecure/keychain/KeychainApplication.java | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index 161979ce3..710dbf8aa 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -40,8 +40,6 @@ import org.sufficientlysecure.keychain.util.PRNGFixes; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.TlsHelper; -import java.io.File; -import java.io.FilenameFilter; import java.security.Security; import java.util.HashMap; @@ -90,17 +88,6 @@ public class KeychainApplication extends Application { } } - // Clean up leftover Bluetooth Share files - for (File toDelete : this.getExternalCacheDir().listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String filename) { - if (filename.matches("^key-[0-9a-fA-F]{8}\\.pgp\\.asc$")) { - return true; - } - return false; - } - })) { toDelete.delete(); } - brandGlowEffect(getApplicationContext(), getApplicationContext().getResources().getColor(R.color.primary)); -- cgit v1.2.3 From aba9c884ce46237ed0633c5a123860e6af8488bc Mon Sep 17 00:00:00 2001 From: William Faulk Date: Mon, 4 May 2015 17:15:51 -0400 Subject: revert unneeded changes for short key ID --- .../keychain/ui/util/KeyFormattingUtils.java | 30 +++------------------- 1 file changed, 3 insertions(+), 27 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java index 0b80b5fe9..91a7d361a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java @@ -227,14 +227,6 @@ public class KeyFormattingUtils { return buf.getLong(); } - public static int getShortKeyIdFromFingerprint(byte[] fingerprint) { - ByteBuffer buf = ByteBuffer.wrap(fingerprint); - // skip first 16 bytes of the fingerprint - buf.position(16); - // the last four bytes are the short key id (big endian, which is default order in ByteBuffer) - return buf.getInt(); - } - /** * Convert key id from long to 64 bit hex string *

@@ -246,24 +238,16 @@ public class KeyFormattingUtils { * @return */ public static String convertKeyIdToHex(long keyId) { - return convertKeyIdToHex(keyId, true); - } - - public static String convertKeyIdToHex(long keyId, boolean header) { long upper = keyId >> 32; if (upper == 0) { // this is a short key id - return convertKeyIdToHexShort(keyId, header); + return convertKeyIdToHexShort(keyId); } - return header?"0x":"" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId); + return "0x" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId); } public static String convertKeyIdToHexShort(long keyId) { - return convertKeyIdToHexShort(keyId, true); - } - - public static String convertKeyIdToHexShort(long keyId, boolean header) { - return header?"0x":"" + convertKeyIdToHex32bit(keyId); + return "0x" + convertKeyIdToHex32bit(keyId); } private static String convertKeyIdToHex32bit(long keyId) { @@ -274,14 +258,6 @@ public class KeyFormattingUtils { return hexString; } - public static String getKeyIdAsHexFromFingerprint(byte[] fingerprint, boolean header) { - return convertKeyIdToHex(getKeyIdFromFingerprint(fingerprint), header); - } - - public static String getShortKeyIdAsHexFromFingerprint(byte[] fingerprint, boolean header) { - return convertKeyIdToHex(getShortKeyIdFromFingerprint(fingerprint), header); - } - /** * Makes a human-readable version of a key ID, which is usually 64 bits: lower-case, no * leading 0x, space-separated quartets (for keys whose length in hex is divisible by 4) -- cgit v1.2.3 From afc91fb9181e6999e7229db05da83cd832687918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 6 May 2015 00:08:04 +0200 Subject: Switch to new library repos --- .../java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java | 2 +- .../java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java | 2 +- .../java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java | 2 +- .../java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java | 2 +- .../java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java | 3 +-- .../org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java | 2 +- 6 files changed, 6 insertions(+), 7 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java index dce2386b5..c9a590c5b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java @@ -25,7 +25,7 @@ import android.view.View; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.api.OpenKeychainIntents; +import org.sufficientlysecure.keychain.intents.OpenKeychainIntents; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.util.Log; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java index 728e3ba41..e2f527cee 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java @@ -26,7 +26,7 @@ import android.view.View; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.api.OpenKeychainIntents; +import org.sufficientlysecure.keychain.intents.OpenKeychainIntents; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.SingletonResult; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java index 64e908b1a..b3ec60890 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java @@ -28,7 +28,7 @@ import android.view.View; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.api.OpenKeychainIntents; +import org.sufficientlysecure.keychain.intents.OpenKeychainIntents; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.util.Passphrase; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java index dd6dd6594..52d098adc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java @@ -26,7 +26,7 @@ import android.view.View; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.api.OpenKeychainIntents; +import org.sufficientlysecure.keychain.intents.OpenKeychainIntents; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Passphrase; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 5d9950db6..4eb01a76c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -30,7 +30,7 @@ import android.view.ViewGroup; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.api.OpenKeychainIntents; +import org.sufficientlysecure.keychain.intents.OpenKeychainIntents; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; @@ -39,7 +39,6 @@ import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity; import org.sufficientlysecure.keychain.service.CloudImportService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; -import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java index 29f2511a0..dc8752d1a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java @@ -37,7 +37,7 @@ import com.google.zxing.integration.android.IntentResult; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.api.OpenKeychainIntents; +import org.sufficientlysecure.keychain.intents.OpenKeychainIntents; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; -- cgit v1.2.3 From f102ae5da5394f63298ed0c49195de8baf496bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 6 May 2015 03:26:42 +0200 Subject: Move error overlay into generalized DecryptFragment, better error handling in DecryptTextActivity --- .../keychain/ui/DecryptFilesFragment.java | 5 +-- .../keychain/ui/DecryptFragment.java | 43 ++++++++++++++++++++-- .../keychain/ui/DecryptTextActivity.java | 19 ++++++---- .../keychain/ui/DecryptTextFragment.java | 29 +-------------- 4 files changed, 55 insertions(+), 41 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java index e5ddcbbd6..96af45dd2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java @@ -31,6 +31,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 org.sufficientlysecure.keychain.Constants; @@ -232,7 +233,6 @@ public class DecryptFilesFragment extends DecryptFragment { returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT); if (pgpResult.success()) { - switch (mCurrentCryptoOperation) { case KeychainIntentService.ACTION_DECRYPT_METADATA: { askForOutputFilename(pgpResult.getDecryptMetadata().getFilename()); @@ -264,9 +264,8 @@ public class DecryptFilesFragment extends DecryptFragment { break; } } - } else { - pgpResult.createNotify(getActivity()).show(); } + pgpResult.createNotify(getActivity()).show(DecryptFilesFragment.this); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index 230f478ae..c5f9821d3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -30,6 +30,7 @@ import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.util.Log; import android.view.View; +import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -61,17 +62,18 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements public static final int LOADER_ID_UNIFIED = 0; protected LinearLayout mResultLayout; - protected ImageView mEncryptionIcon; protected TextView mEncryptionText; protected ImageView mSignatureIcon; protected TextView mSignatureText; - protected View mSignatureLayout; protected TextView mSignatureName; protected TextView mSignatureEmail; protected TextView mSignatureAction; + private LinearLayout mContentLayout; + private LinearLayout mErrorOverlayLayout; + private OpenPgpSignatureResult mSignatureResult; @Override @@ -81,7 +83,6 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements // NOTE: These views are inside the activity! mResultLayout = (LinearLayout) getActivity().findViewById(R.id.result_main_layout); mResultLayout.setVisibility(View.GONE); - mEncryptionIcon = (ImageView) getActivity().findViewById(R.id.result_encryption_icon); mEncryptionText = (TextView) getActivity().findViewById(R.id.result_encryption_text); mSignatureIcon = (ImageView) getActivity().findViewById(R.id.result_signature_icon); @@ -90,6 +91,18 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements mSignatureName = (TextView) getActivity().findViewById(R.id.result_signature_name); mSignatureEmail = (TextView) getActivity().findViewById(R.id.result_signature_email); mSignatureAction = (TextView) getActivity().findViewById(R.id.result_signature_action); + + // Overlay + mContentLayout = (LinearLayout) view.findViewById(R.id.decrypt_content); + mErrorOverlayLayout = (LinearLayout) view.findViewById(R.id.decrypt_error_overlay); + Button vErrorOverlayButton = (Button) view.findViewById(R.id.decrypt_error_overlay_button); + vErrorOverlayButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mErrorOverlayLayout.setVisibility(View.GONE); + mContentLayout.setVisibility(View.VISIBLE); + } + }); } private void lookupUnknownKey(long unknownKeyId) { @@ -185,6 +198,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements getLoaderManager().destroyLoader(LOADER_ID_UNIFIED); + mErrorOverlayLayout.setVisibility(View.GONE); + mContentLayout.setVisibility(View.VISIBLE); + onVerifyLoaded(true); return; @@ -285,6 +301,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements setSignatureLayoutVisibility(View.VISIBLE); setShowAction(signatureKeyId); + mErrorOverlayLayout.setVisibility(View.VISIBLE); + mContentLayout.setVisibility(View.GONE); + onVerifyLoaded(false); } else if (isExpired) { @@ -294,6 +313,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements setSignatureLayoutVisibility(View.VISIBLE); setShowAction(signatureKeyId); + mErrorOverlayLayout.setVisibility(View.GONE); + mContentLayout.setVisibility(View.VISIBLE); + onVerifyLoaded(true); } else if (isYours) { @@ -304,6 +326,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements setSignatureLayoutVisibility(View.VISIBLE); setShowAction(signatureKeyId); + mErrorOverlayLayout.setVisibility(View.GONE); + mContentLayout.setVisibility(View.VISIBLE); + onVerifyLoaded(true); } else if (isVerified) { @@ -313,6 +338,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements setSignatureLayoutVisibility(View.VISIBLE); setShowAction(signatureKeyId); + mErrorOverlayLayout.setVisibility(View.GONE); + mContentLayout.setVisibility(View.VISIBLE); + onVerifyLoaded(true); } else { @@ -322,6 +350,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements setSignatureLayoutVisibility(View.VISIBLE); setShowAction(signatureKeyId); + mErrorOverlayLayout.setVisibility(View.GONE); + mContentLayout.setVisibility(View.VISIBLE); + onVerifyLoaded(true); } @@ -378,6 +409,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements } }); + mErrorOverlayLayout.setVisibility(View.GONE); + mContentLayout.setVisibility(View.VISIBLE); + onVerifyLoaded(true); break; @@ -389,6 +423,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements setSignatureLayoutVisibility(View.GONE); + mErrorOverlayLayout.setVisibility(View.VISIBLE); + mContentLayout.setVisibility(View.GONE); + onVerifyLoaded(false); break; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java index e2f527cee..e2eba3947 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2012-2015 Dominik Schürmann * Copyright (C) 2010-2014 Thialfihar * * This program is free software: you can redistribute it and/or modify @@ -23,16 +23,16 @@ import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import android.view.View; +import android.widget.Toast; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.intents.OpenKeychainIntents; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; +import org.sufficientlysecure.keychain.intents.OpenKeychainIntents; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.SingletonResult; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.ui.base.BaseActivity; -import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; import java.util.regex.Matcher; @@ -138,8 +138,6 @@ public class DecryptTextActivity extends BaseActivity { /** * Handles all actions with this intent - * - * @param intent */ private void handleActions(Bundle savedInstanceState, Intent intent) { String action = intent.getAction(); @@ -162,10 +160,14 @@ public class DecryptTextActivity extends BaseActivity { if (sharedText != null) { loadFragment(savedInstanceState, sharedText); } else { - Notify.create(this, R.string.error_invalid_data, Notify.Style.ERROR).show(); + Log.e(Constants.TAG, "EXTRA_TEXT does not contain PGP content!"); + Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show(); + finish(); } } else { Log.e(Constants.TAG, "ACTION_SEND received non-plaintext, this should not happen in this activity!"); + Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show(); + finish(); } } else if (ACTION_DECRYPT_TEXT.equals(action)) { Log.d(Constants.TAG, "ACTION_DECRYPT_TEXT"); @@ -176,7 +178,9 @@ public class DecryptTextActivity extends BaseActivity { if (extraText != null) { loadFragment(savedInstanceState, extraText); } else { - Notify.create(this, R.string.error_invalid_data, Notify.Style.ERROR).show(); + Log.e(Constants.TAG, "EXTRA_TEXT does not contain PGP content!"); + Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show(); + finish(); } } else if (ACTION_DECRYPT_FROM_CLIPBOARD.equals(action)) { Log.d(Constants.TAG, "ACTION_DECRYPT_FROM_CLIPBOARD"); @@ -191,6 +195,7 @@ public class DecryptTextActivity extends BaseActivity { } } else if (ACTION_DECRYPT_TEXT.equals(action)) { Log.e(Constants.TAG, "Include the extra 'text' in your Intent!"); + Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show(); finish(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java index b8f1aee63..381da6f0d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java @@ -50,8 +50,6 @@ public class DecryptTextFragment extends DecryptFragment { public static final String ARG_CIPHERTEXT = "ciphertext"; // view - private LinearLayout mContentLayout; - private LinearLayout mErrorOverlayLayout; private TextView mText; // model @@ -78,19 +76,8 @@ public class DecryptTextFragment extends DecryptFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.decrypt_text_fragment, container, false); - mContentLayout = (LinearLayout) view.findViewById(R.id.decrypt_content); - mErrorOverlayLayout = (LinearLayout) view.findViewById(R.id.decrypt_error_overlay); mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext); - Button vErrorOverlayButton = (Button) view.findViewById(R.id.decrypt_error_overlay_button); - vErrorOverlayButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mErrorOverlayLayout.setVisibility(View.GONE); - mContentLayout.setVisibility(View.VISIBLE); - } - }); - return view; } @@ -203,7 +190,6 @@ public class DecryptTextFragment extends DecryptFragment { returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT); if (pgpResult.success()) { - byte[] decryptedMessage = returnData .getByteArray(KeychainIntentService.RESULT_DECRYPTED_BYTES); String displayMessage; @@ -219,15 +205,12 @@ public class DecryptTextFragment extends DecryptFragment { } mText.setText(displayMessage); - pgpResult.createNotify(getActivity()).show(); - // display signature result in activity loadVerifyResult(pgpResult); - } else { - pgpResult.createNotify(getActivity()).show(); // TODO: show also invalid layout with different text? } + pgpResult.createNotify(getActivity()).show(DecryptTextFragment.this); } } }; @@ -245,17 +228,7 @@ public class DecryptTextFragment extends DecryptFragment { @Override protected void onVerifyLoaded(boolean hideErrorOverlay) { - mShowMenuOptions = hideErrorOverlay; getActivity().supportInvalidateOptionsMenu(); - - if (hideErrorOverlay) { - mErrorOverlayLayout.setVisibility(View.GONE); - mContentLayout.setVisibility(View.VISIBLE); - } else { - mErrorOverlayLayout.setVisibility(View.VISIBLE); - mContentLayout.setVisibility(View.GONE); - } - } } -- cgit v1.2.3 From 8de6589c9d4d6b9278ed4f46da7adbb6b81f1e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 6 May 2015 03:29:04 +0200 Subject: Renaming for consisitency --- .../sufficientlysecure/keychain/ui/DecryptFilesFragment.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java index 96af45dd2..234362edc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java @@ -31,7 +31,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 org.sufficientlysecure.keychain.Constants; @@ -87,12 +86,12 @@ public class DecryptFilesFragment extends DecryptFragment { */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.decrypt_file_fragment, container, false); + View view = inflater.inflate(R.layout.decrypt_files_fragment, container, false); - mFilename = (TextView) view.findViewById(R.id.decrypt_file_filename); - mDeleteAfter = (CheckBox) view.findViewById(R.id.decrypt_file_delete_after_decryption); - mDecryptButton = view.findViewById(R.id.decrypt_file_action_decrypt); - view.findViewById(R.id.decrypt_file_browse).setOnClickListener(new View.OnClickListener() { + mFilename = (TextView) view.findViewById(R.id.decrypt_files_filename); + mDeleteAfter = (CheckBox) view.findViewById(R.id.decrypt_files_delete_after_decryption); + mDecryptButton = view.findViewById(R.id.decrypt_files_action_decrypt); + view.findViewById(R.id.decrypt_files_browse).setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { FileHelper.openDocument(DecryptFilesFragment.this, "*/*", REQUEST_CODE_INPUT); -- cgit v1.2.3 From d2998ea80db5a7dee97ae5fc2301db3a13e472b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 6 May 2015 03:37:57 +0200 Subject: Rename for consistency --- .../keychain/ui/CreateKeyActivity.java | 5 +- .../keychain/ui/CreateKeyYubiImportFragment.java | 262 --------------------- .../ui/CreateKeyYubiKeyImportFragment.java | 262 +++++++++++++++++++++ 3 files changed, 264 insertions(+), 265 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiImportFragment.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java index dfb94ebb9..e0b728bd4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java @@ -20,7 +20,6 @@ package org.sufficientlysecure.keychain.ui; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import org.sufficientlysecure.keychain.R; @@ -84,7 +83,7 @@ public class CreateKeyActivity extends BaseNfcActivity { String nfcUserId = intent.getStringExtra(EXTRA_NFC_USER_ID); byte[] nfcAid = intent.getByteArrayExtra(EXTRA_NFC_AID); - Fragment frag2 = CreateKeyYubiImportFragment.createInstance( + Fragment frag2 = CreateKeyYubiKeyImportFragment.createInstance( nfcFingerprints, nfcAid, nfcUserId); loadFragment(frag2, FragAction.START); @@ -131,7 +130,7 @@ public class CreateKeyActivity extends BaseNfcActivity { finish(); } catch (PgpKeyNotFoundException e) { - Fragment frag = CreateKeyYubiImportFragment.createInstance( + Fragment frag = CreateKeyYubiKeyImportFragment.createInstance( scannedFingerprints, nfcAid, userId); loadFragment(frag, FragAction.TO_RIGHT); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiImportFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiImportFragment.java deleted file mode 100644 index db62d53c5..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiImportFragment.java +++ /dev/null @@ -1,262 +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; - -import java.io.IOException; -import java.util.ArrayList; - -import android.app.Activity; -import android.app.ProgressDialog; -import android.content.Intent; -import android.os.Bundle; -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; -import android.view.ViewGroup; -import android.widget.TextView; - -import org.spongycastle.util.encoders.Hex; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; -import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; -import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; -import org.sufficientlysecure.keychain.service.KeychainIntentService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; -import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; -import org.sufficientlysecure.keychain.ui.CreateKeyActivity.NfcListenerFragment; -import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; -import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -import org.sufficientlysecure.keychain.util.Preferences; - - -public class CreateKeyYubiImportFragment extends Fragment implements NfcListenerFragment { - - private static final String ARG_FINGERPRINT = "fingerprint"; - public static final String ARG_AID = "aid"; - public static final String ARG_USER_ID = "user_ids"; - - CreateKeyActivity mCreateKeyActivity; - - private byte[] mNfcFingerprints; - private long mNfcMasterKeyId; - private byte[] mNfcAid; - private String mNfcUserId; - private String mNfcFingerprint; - private ImportKeysListFragment mListFragment; - private TextView vSerNo; - private TextView vUserId; - - public static Fragment createInstance(byte[] scannedFingerprints, byte[] nfcAid, String userId) { - - CreateKeyYubiImportFragment frag = new CreateKeyYubiImportFragment(); - - Bundle args = new Bundle(); - args.putByteArray(ARG_FINGERPRINT, scannedFingerprints); - args.putByteArray(ARG_AID, nfcAid); - args.putString(ARG_USER_ID, userId); - frag.setArguments(args); - - return frag; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Bundle args = savedInstanceState != null ? savedInstanceState : getArguments(); - - mNfcFingerprints = args.getByteArray(ARG_FINGERPRINT); - mNfcAid = args.getByteArray(ARG_AID); - mNfcUserId = args.getString(ARG_USER_ID); - - mNfcMasterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(mNfcFingerprints); - mNfcFingerprint = KeyFormattingUtils.convertFingerprintToHex(mNfcFingerprints); - - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.create_yubikey_import_fragment, container, false); - - vSerNo = (TextView) view.findViewById(R.id.yubikey_serno); - vUserId = (TextView) view.findViewById(R.id.yubikey_userid); - - { - View mBackButton = view.findViewById(R.id.create_key_back_button); - mBackButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (getFragmentManager().getBackStackEntryCount() == 0) { - getActivity().setResult(Activity.RESULT_CANCELED); - getActivity().finish(); - } else { - mCreateKeyActivity.loadFragment(null, FragAction.TO_LEFT); - } - } - }); - - View mNextButton = view.findViewById(R.id.create_key_next_button); - mNextButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - importKey(); - } - }); - } - - mListFragment = ImportKeysListFragment.newInstance(null, null, - "0x" + mNfcFingerprint, true, null); - - view.findViewById(R.id.button_search).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - refreshSearch(); - } - }); - - setData(); - - getFragmentManager().beginTransaction() - .replace(R.id.yubikey_import_fragment, mListFragment, "yubikey_import") - .commit(); - - return view; - } - - @Override - public void onSaveInstanceState(Bundle args) { - super.onSaveInstanceState(args); - - args.putByteArray(ARG_FINGERPRINT, mNfcFingerprints); - args.putByteArray(ARG_AID, mNfcAid); - args.putString(ARG_USER_ID, mNfcUserId); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - mCreateKeyActivity = (CreateKeyActivity) getActivity(); - } - - public void setData() { - String serno = Hex.toHexString(mNfcAid, 10, 4); - vSerNo.setText(getString(R.string.yubikey_serno, serno)); - - if (!mNfcUserId.isEmpty()) { - vUserId.setText(getString(R.string.yubikey_key_holder, mNfcUserId)); - } else { - vUserId.setText(getString(R.string.yubikey_key_holder_unset)); - } - } - - public void refreshSearch() { - mListFragment.loadNew(new ImportKeysListFragment.CloudLoaderState("0x" + mNfcFingerprint, - Preferences.getPreferences(getActivity()).getCloudSearchPrefs())); - } - - public void importKey() { - - // Message is received after decrypting is done in KeychainIntentService - ServiceProgressHandler saveHandler = new ServiceProgressHandler( - getActivity(), - getString(R.string.progress_importing), - ProgressDialog.STYLE_HORIZONTAL, - ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT - ) { - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - - ImportKeyResult result = - returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT); - - if (!result.success()) { - result.createNotify(getActivity()).show(); - return; - } - - Intent intent = new Intent(getActivity(), ViewKeyActivity.class); - intent.setData(KeyRings.buildGenericKeyRingUri(mNfcMasterKeyId)); - intent.putExtra(ViewKeyActivity.EXTRA_DISPLAY_RESULT, result); - intent.putExtra(ViewKeyActivity.EXTRA_NFC_AID, mNfcAid); - intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, mNfcUserId); - intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, mNfcFingerprints); - startActivity(intent); - getActivity().finish(); - - } - - } - }; - - // 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_IMPORT_KEYRING); - - String hexFp = KeyFormattingUtils.convertFingerprintToHex(mNfcFingerprints); - ArrayList keyList = new ArrayList<>(); - keyList.add(new ParcelableKeyRing(hexFp, null, null)); - data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, keyList); - - { - Preferences prefs = Preferences.getPreferences(getActivity()); - Preferences.CloudSearchPrefs cloudPrefs = - new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver()); - data.putString(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); - } - - intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - - saveHandler.showProgressDialog(getActivity()); - - // start service with intent - getActivity().startService(intent); - - } - - @Override - public void onNfcPerform() throws IOException { - - mNfcFingerprints = mCreateKeyActivity.nfcGetFingerprints(); - mNfcAid = mCreateKeyActivity.nfcGetAid(); - mNfcUserId = mCreateKeyActivity.nfcGetUserId(); - - mNfcMasterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(mNfcFingerprints); - mNfcFingerprint = KeyFormattingUtils.convertFingerprintToHex(mNfcFingerprints); - - setData(); - refreshSearch(); - - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java new file mode 100644 index 000000000..4c7d1dfbd --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java @@ -0,0 +1,262 @@ +/* + * 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 java.io.IOException; +import java.util.ArrayList; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.Bundle; +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; +import android.view.ViewGroup; +import android.widget.TextView; + +import org.spongycastle.util.encoders.Hex; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; +import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; +import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; +import org.sufficientlysecure.keychain.ui.CreateKeyActivity.NfcListenerFragment; +import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; +import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import org.sufficientlysecure.keychain.util.Preferences; + + +public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListenerFragment { + + private static final String ARG_FINGERPRINT = "fingerprint"; + public static final String ARG_AID = "aid"; + public static final String ARG_USER_ID = "user_ids"; + + CreateKeyActivity mCreateKeyActivity; + + private byte[] mNfcFingerprints; + private long mNfcMasterKeyId; + private byte[] mNfcAid; + private String mNfcUserId; + private String mNfcFingerprint; + private ImportKeysListFragment mListFragment; + private TextView vSerNo; + private TextView vUserId; + + public static Fragment createInstance(byte[] scannedFingerprints, byte[] nfcAid, String userId) { + + CreateKeyYubiKeyImportFragment frag = new CreateKeyYubiKeyImportFragment(); + + Bundle args = new Bundle(); + args.putByteArray(ARG_FINGERPRINT, scannedFingerprints); + args.putByteArray(ARG_AID, nfcAid); + args.putString(ARG_USER_ID, userId); + frag.setArguments(args); + + return frag; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Bundle args = savedInstanceState != null ? savedInstanceState : getArguments(); + + mNfcFingerprints = args.getByteArray(ARG_FINGERPRINT); + mNfcAid = args.getByteArray(ARG_AID); + mNfcUserId = args.getString(ARG_USER_ID); + + mNfcMasterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(mNfcFingerprints); + mNfcFingerprint = KeyFormattingUtils.convertFingerprintToHex(mNfcFingerprints); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.create_yubikey_import_fragment, container, false); + + vSerNo = (TextView) view.findViewById(R.id.yubikey_serno); + vUserId = (TextView) view.findViewById(R.id.yubikey_userid); + + { + View mBackButton = view.findViewById(R.id.create_key_back_button); + mBackButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (getFragmentManager().getBackStackEntryCount() == 0) { + getActivity().setResult(Activity.RESULT_CANCELED); + getActivity().finish(); + } else { + mCreateKeyActivity.loadFragment(null, FragAction.TO_LEFT); + } + } + }); + + View mNextButton = view.findViewById(R.id.create_key_next_button); + mNextButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + importKey(); + } + }); + } + + mListFragment = ImportKeysListFragment.newInstance(null, null, + "0x" + mNfcFingerprint, true, null); + + view.findViewById(R.id.button_search).setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + refreshSearch(); + } + }); + + setData(); + + getFragmentManager().beginTransaction() + .replace(R.id.yubikey_import_fragment, mListFragment, "yubikey_import") + .commit(); + + return view; + } + + @Override + public void onSaveInstanceState(Bundle args) { + super.onSaveInstanceState(args); + + args.putByteArray(ARG_FINGERPRINT, mNfcFingerprints); + args.putByteArray(ARG_AID, mNfcAid); + args.putString(ARG_USER_ID, mNfcUserId); + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + mCreateKeyActivity = (CreateKeyActivity) getActivity(); + } + + public void setData() { + String serno = Hex.toHexString(mNfcAid, 10, 4); + vSerNo.setText(getString(R.string.yubikey_serno, serno)); + + if (!mNfcUserId.isEmpty()) { + vUserId.setText(getString(R.string.yubikey_key_holder, mNfcUserId)); + } else { + vUserId.setText(getString(R.string.yubikey_key_holder_unset)); + } + } + + public void refreshSearch() { + mListFragment.loadNew(new ImportKeysListFragment.CloudLoaderState("0x" + mNfcFingerprint, + Preferences.getPreferences(getActivity()).getCloudSearchPrefs())); + } + + public void importKey() { + + // Message is received after decrypting is done in KeychainIntentService + ServiceProgressHandler saveHandler = new ServiceProgressHandler( + getActivity(), + getString(R.string.progress_importing), + ProgressDialog.STYLE_HORIZONTAL, + ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT + ) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == MessageStatus.OKAY.ordinal()) { + // get returned data bundle + Bundle returnData = message.getData(); + + ImportKeyResult result = + returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT); + + if (!result.success()) { + result.createNotify(getActivity()).show(); + return; + } + + Intent intent = new Intent(getActivity(), ViewKeyActivity.class); + intent.setData(KeyRings.buildGenericKeyRingUri(mNfcMasterKeyId)); + intent.putExtra(ViewKeyActivity.EXTRA_DISPLAY_RESULT, result); + intent.putExtra(ViewKeyActivity.EXTRA_NFC_AID, mNfcAid); + intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, mNfcUserId); + intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, mNfcFingerprints); + startActivity(intent); + getActivity().finish(); + + } + + } + }; + + // 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_IMPORT_KEYRING); + + String hexFp = KeyFormattingUtils.convertFingerprintToHex(mNfcFingerprints); + ArrayList keyList = new ArrayList<>(); + keyList.add(new ParcelableKeyRing(hexFp, null, null)); + data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, keyList); + + { + Preferences prefs = Preferences.getPreferences(getActivity()); + Preferences.CloudSearchPrefs cloudPrefs = + new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver()); + data.putString(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); + } + + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + saveHandler.showProgressDialog(getActivity()); + + // start service with intent + getActivity().startService(intent); + + } + + @Override + public void onNfcPerform() throws IOException { + + mNfcFingerprints = mCreateKeyActivity.nfcGetFingerprints(); + mNfcAid = mCreateKeyActivity.nfcGetAid(); + mNfcUserId = mCreateKeyActivity.nfcGetUserId(); + + mNfcMasterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(mNfcFingerprints); + mNfcFingerprint = KeyFormattingUtils.convertFingerprintToHex(mNfcFingerprints); + + setData(); + refreshSearch(); + + } +} -- cgit v1.2.3 From a45aaa2277422b2bc1521f9237f0ec6c5684bd0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 6 May 2015 04:10:27 +0200 Subject: Fix import of keyring with pub+sec key with same key id --- .../keychain/service/CloudImportService.java | 19 ++-- .../keychain/ui/ImportKeysActivity.java | 123 ++++++++++++--------- 2 files changed, 80 insertions(+), 62 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CloudImportService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CloudImportService.java index 180109297..249586f6d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CloudImportService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CloudImportService.java @@ -50,18 +50,18 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public class CloudImportService extends Service implements Progressable { - //required as extras from intent + // required as extras from intent public static final String EXTRA_MESSENGER = "messenger"; public static final String EXTRA_DATA = "data"; - //required by data bundle + // required by data bundle public static final String IMPORT_KEY_LIST = "import_key_list"; public static final String IMPORT_KEY_SERVER = "import_key_server"; // indicates a request to cancel the import public static final String ACTION_CANCEL = Constants.INTENT_PREFIX + "CANCEL"; - //tells the spawned threads whether the user has requested a cancel + // tells the spawned threads whether the user has requested a cancel private static AtomicBoolean mActionCancelled = new AtomicBoolean(false); @Override @@ -86,7 +86,7 @@ public class CloudImportService extends Service implements Progressable { public KeyImportAccumulator(int totalKeys) { mTotalKeys = totalKeys; - //ignore updates from ImportExportOperation for now + // ignore updates from ImportExportOperation for now mImportProgressable = new Progressable() { @Override public void setProgress(String message, int current, int total) { @@ -131,20 +131,17 @@ public class CloudImportService extends Service implements Progressable { mSecret += result.mSecret; long[] masterKeyIds = result.getImportedMasterKeyIds(); - for (int i = 0; i < masterKeyIds.length; i++) { - mImportedMasterKeyIds.add(masterKeyIds[i]); + for (long masterKeyId : masterKeyIds) { + mImportedMasterKeyIds.add(masterKeyId); } // if any key import has been cancelled, set result type to cancelled // resultType is added to in getConsolidatedKayImport to account for remaining factors mResultType |= result.getResult() & ImportKeyResult.RESULT_CANCELLED; - } /** * returns accumulated result of all imports so far - * - * @return */ public ImportKeyResult getConsolidatedImportKeyResult() { @@ -205,7 +202,7 @@ public class CloudImportService extends Service implements Progressable { Bundle data = extras.getBundle(EXTRA_DATA); final String keyServer = data.getString(IMPORT_KEY_SERVER); - //keyList being null (in case key list to be reaad from cache) is checked by importKeys + // keyList being null (in case key list to be reaad from cache) is checked by importKeys final ArrayList keyList = data.getParcelableArrayList(IMPORT_KEY_LIST); // Adding keys to the ThreadPoolExecutor takes time, we don't want to block the main thread @@ -225,7 +222,7 @@ public class CloudImportService extends Service implements Progressable { new ParcelableFileCache<>(this, "key_import.pcl"); int totKeys = 0; Iterator keyListIterator = null; - //either keyList or cache must be null, no guarantees otherwise + // either keyList or cache must be null, no guarantees otherwise if (keyList == null) {//export from cache, copied from ImportExportOperation.importKeyRings try { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 4eb01a76c..4cba62d5b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -35,6 +35,7 @@ import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity; import org.sufficientlysecure.keychain.service.CloudImportService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; @@ -345,60 +346,66 @@ public class ImportKeysActivity extends BaseNfcActivity { mListFragment.loadNew(loaderState); } + private void handleMessage(Message message) { + if (message.arg1 == ServiceProgressHandler.MessageStatus.OKAY.ordinal()) { + // get returned data bundle + Bundle returnData = message.getData(); + if (returnData == null) { + return; + } + final ImportKeyResult result = + returnData.getParcelable(OperationResult.EXTRA_RESULT); + if (result == null) { + Log.e(Constants.TAG, "result == null"); + return; + } + + if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(getIntent().getAction()) + || ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(getIntent().getAction())) { + Intent intent = new Intent(); + intent.putExtra(ImportKeyResult.EXTRA_RESULT, result); + ImportKeysActivity.this.setResult(RESULT_OK, intent); + ImportKeysActivity.this.finish(); + return; + } + if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE.equals(getIntent().getAction())) { + ImportKeysActivity.this.setResult(RESULT_OK, mPendingIntentData); + ImportKeysActivity.this.finish(); + return; + } + + result.createNotify(ImportKeysActivity.this) + .show((ViewGroup) findViewById(R.id.import_snackbar)); + } + } + /** * Import keys with mImportData */ public void importKeys() { - // Message is received after importing is done in CloudImportService - ServiceProgressHandler saveHandler = new ServiceProgressHandler( - this, - getString(R.string.progress_importing), - ProgressDialog.STYLE_HORIZONTAL, - true, - ProgressDialogFragment.ServiceType.CLOUD_IMPORT) { - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - if (returnData == null) { - return; - } - final ImportKeyResult result = - returnData.getParcelable(OperationResult.EXTRA_RESULT); - if (result == null) { - Log.e(Constants.TAG, "result == null"); - return; - } - - if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(getIntent().getAction()) - || ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(getIntent().getAction())) { - Intent intent = new Intent(); - intent.putExtra(ImportKeyResult.EXTRA_RESULT, result); - ImportKeysActivity.this.setResult(RESULT_OK, intent); - ImportKeysActivity.this.finish(); - return; - } - if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE.equals(getIntent().getAction())) { - ImportKeysActivity.this.setResult(RESULT_OK, mPendingIntentData); - ImportKeysActivity.this.finish(); - return; - } - - result.createNotify(ImportKeysActivity.this) - .show((ViewGroup) findViewById(R.id.import_snackbar)); - } - } - }; - ImportKeysListFragment.LoaderState ls = mListFragment.getLoaderState(); if (ls instanceof ImportKeysListFragment.BytesLoaderState) { Log.d(Constants.TAG, "importKeys started"); + ServiceProgressHandler serviceHandler = new ServiceProgressHandler( + this, + getString(R.string.progress_importing), + ProgressDialog.STYLE_HORIZONTAL, + true, + ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + ImportKeysActivity.this.handleMessage(message); + } + }; + + // TODO: Currently not using CloudImport here due to https://github.com/open-keychain/open-keychain/issues/1221 // Send all information needed to service to import key in other thread - Intent intent = new Intent(this, CloudImportService.class); + Intent intent = new Intent(this, KeychainIntentService.class); + + intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING); // fill values for this action Bundle data = new Bundle(); @@ -416,14 +423,14 @@ public class ImportKeysActivity extends BaseNfcActivity { new ParcelableFileCache<>(this, "key_import.pcl"); cache.writeCache(selectedEntries); - intent.putExtra(CloudImportService.EXTRA_DATA, data); + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(CloudImportService.EXTRA_MESSENGER, messenger); + Messenger messenger = new Messenger(serviceHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); // show progress dialog - saveHandler.showProgressDialog(this); + serviceHandler.showProgressDialog(this); // start service with intent startService(intent); @@ -435,6 +442,20 @@ public class ImportKeysActivity extends BaseNfcActivity { } else if (ls instanceof ImportKeysListFragment.CloudLoaderState) { ImportKeysListFragment.CloudLoaderState sls = (ImportKeysListFragment.CloudLoaderState) ls; + ServiceProgressHandler serviceHandler = new ServiceProgressHandler( + this, + getString(R.string.progress_importing), + ProgressDialog.STYLE_HORIZONTAL, + true, + ProgressDialogFragment.ServiceType.CLOUD_IMPORT) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + ImportKeysActivity.this.handleMessage(message); + } + }; + // Send all information needed to service to query keys in other thread Intent intent = new Intent(this, CloudImportService.class); @@ -459,11 +480,11 @@ public class ImportKeysActivity extends BaseNfcActivity { intent.putExtra(CloudImportService.EXTRA_DATA, data); // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); + Messenger messenger = new Messenger(serviceHandler); intent.putExtra(CloudImportService.EXTRA_MESSENGER, messenger); // show progress dialog - saveHandler.showProgressDialog(this); + serviceHandler.showProgressDialog(this); // start service with intent startService(intent); -- cgit v1.2.3 From 91d500b20dba3d83085e4cca8836a4eaff24f113 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 6 May 2015 11:25:29 +0200 Subject: check for fingerprint of any subkey (arguable?) --- .../keychain/operations/ImportExportOperation.java | 13 +++++++------ .../sufficientlysecure/keychain/pgp/UncachedKeyRing.java | 11 +++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java index ff0b545cd..b48a1da91 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java @@ -275,7 +275,7 @@ public class ImportExportOperation extends BaseOperation { // If we have an expected fingerprint, make sure it matches if (entry.mExpectedFingerprint != null) { - if(!KeyFormattingUtils.convertFingerprintToHex(key.getFingerprint()).equals(entry.mExpectedFingerprint)) { + if (!key.containsSubkey(entry.mExpectedFingerprint)) { log.add(LogType.MSG_IMPORT_FINGERPRINT_ERROR, 2); badKeys += 1; continue; @@ -314,10 +314,7 @@ public class ImportExportOperation extends BaseOperation { log.add(result, 2); - } catch (IOException e) { - Log.e(Constants.TAG, "Encountered bad key on import!", e); - ++badKeys; - } catch (PgpGeneralException e) { + } catch (IOException | PgpGeneralException e) { Log.e(Constants.TAG, "Encountered bad key on import!", e); ++badKeys; } @@ -460,6 +457,7 @@ public class ImportExportOperation extends BaseOperation { int okSecret = 0, okPublic = 0, progress = 0; + Cursor cursor = null; try { String selection = null, ids[] = null; @@ -480,7 +478,7 @@ public class ImportExportOperation extends BaseOperation { + " IN (" + placeholders + ")"; } - Cursor cursor = mProviderHelper.getContentResolver().query( + cursor = mProviderHelper.getContentResolver().query( KeyRings.buildUnifiedKeyRingsUri(), new String[]{ KeyRings.MASTER_KEY_ID, KeyRings.PUBKEY_DATA, KeyRings.PRIVKEY_DATA, KeyRings.HAS_ANY_SECRET @@ -569,6 +567,9 @@ public class ImportExportOperation extends BaseOperation { } catch (Exception e) { Log.e(Constants.TAG, "error closing stream", e); } + if (cursor != null) { + cursor.close(); + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index b86618a9a..2bb4f7dc4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -215,6 +215,17 @@ public class UncachedKeyRing { } + public boolean containsSubkey(String expectedFingerprint) { + Iterator it = mRing.getPublicKeys(); + while (it.hasNext()) { + if (KeyFormattingUtils.convertFingerprintToHex( + it.next().getFingerprint()).equals(expectedFingerprint)) { + return true; + } + } + return false; + } + public interface IteratorWithIOThrow { public boolean hasNext() throws IOException; public E next() throws IOException; -- cgit v1.2.3 From 797cd289978055d48cfb0f7a39d94d123c0a30a9 Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Fri, 8 May 2015 19:05:21 +0530 Subject: fixed sync on key import, 'me' linked contact crash --- .../keychain/operations/ImportExportOperation.java | 2 + .../keychain/ui/ViewKeyFragment.java | 2 + .../keychain/util/ContactHelper.java | 49 +++++++++++++++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java index b48a1da91..86cfc21a3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java @@ -376,6 +376,8 @@ public class ImportExportOperation extends BaseOperation { log.add(LogType.MSG_IMPORT_ERROR, 1); } + ContactSyncAdapterService.requestSync(); + return new ImportKeyResult(resultType, log, newKeys, updatedKeys, badKeys, secret, importedMasterKeyIdsArray); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java index 1e02ca450..b92163b59 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java @@ -133,6 +133,8 @@ public class ViewKeyFragment extends LoaderFragment implements * @param contactId */ private void loadLinkedSystemContact(final long contactId) { + // contact doesn't exist, stop + if(contactId == -1) return; final Context context = mSystemContactName.getContext(); final ContentResolver resolver = context.getContentResolver(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java index 609288bf1..e1efd5abc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java @@ -446,6 +446,13 @@ public class ContactHelper { writeKeysToMainProfileContact(context, resolver); + writeKeysToNormalContacts(context, resolver); + } + + private static void writeKeysToNormalContacts(Context context, ContentResolver resolver) { + // delete raw contacts flagged for deletion by user so they can be reinserted + deleteFlaggedNormalRawContacts(resolver); + Set deletedKeys = getRawContactMasterKeyIds(resolver); // Load all public Keys from OK @@ -519,6 +526,9 @@ public class ContactHelper { * @param context */ public static void writeKeysToMainProfileContact(Context context, ContentResolver resolver) { + // deletes contacts hidden by the user so they can be reinserted if necessary + deleteFlaggedMainProfileRawContacts(resolver); + Set keysToDelete = getMainProfileMasterKeyIds(resolver); // get all keys which have associated secret keys @@ -585,7 +595,7 @@ public class ContactHelper { * * @param resolver * @param masterKeyId - * @return + * @return number of rows deleted */ private static int deleteMainProfileRawContactByMasterKeyId(ContentResolver resolver, long masterKeyId) { @@ -602,6 +612,28 @@ public class ContactHelper { }); } + /** + * deletes all raw contact entries in the "me" contact flagged for deletion ('hidden'), + * presumably by the user + * + * @param resolver + * @return number of raw contacts deleted + */ + private static int deleteFlaggedMainProfileRawContacts(ContentResolver resolver) { + // CALLER_IS_SYNCADAPTER allows us to actually wipe the RawContact from the device, otherwise + // would be just flagged for deletion + Uri deleteUri = ContactsContract.Profile.CONTENT_RAW_CONTACTS_URI.buildUpon(). + appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build(); + + return resolver.delete(deleteUri, + ContactsContract.RawContacts.ACCOUNT_TYPE + "=? AND " + + ContactsContract.RawContacts.DELETED + "=?", + new String[]{ + Constants.ACCOUNT_TYPE, + "1" + }); + } + /** * Delete all raw contacts associated to OpenKeychain, including those from "me" contact * defined by ContactsContract.Profile @@ -677,6 +709,21 @@ public class ContactHelper { }); } + private static int deleteFlaggedNormalRawContacts(ContentResolver resolver) { + // CALLER_IS_SYNCADAPTER allows us to actually wipe the RawContact from the device, otherwise + // would be just flagged for deletion + Uri deleteUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon(). + appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build(); + + return resolver.delete(deleteUri, + ContactsContract.RawContacts.ACCOUNT_TYPE + "=? AND " + + ContactsContract.RawContacts.DELETED + "=?", + new String[]{ + Constants.ACCOUNT_TYPE, + "1" + }); + } + /** * @return a set of all key master key ids currently present in the contact db */ -- cgit v1.2.3 From 6e326fb000e4fbe11452671d14dce02cade1d292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 10 May 2015 03:00:42 +0200 Subject: Add self-encrypt for old API --- .../sufficientlysecure/keychain/remote/OpenPgpService.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index badc3c131..4a8bf9332 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -417,6 +417,20 @@ public class OpenPgpService extends RemoteService { .setAdditionalEncryptId(signKeyId); // add sign key for encryption } + // OLD: Even if the message is not signed: Do self-encrypt to account key id + if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 7) { + String accName = data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME); + // if no account name is given use name "default" + if (TextUtils.isEmpty(accName)) { + accName = "default"; + } + final AccountSettings accSettings = getAccSettings(accName); + if (accSettings == null || (accSettings.getKeyId() == Constants.key.none)) { + return getCreateAccountIntent(data, accName); + } + pseInput.setAdditionalEncryptId(accSettings.getKeyId()); + } + CryptoInputParcel inputParcel = CryptoInputParcelCacheService.getCryptoInputParcel(this, data); if (inputParcel == null) { inputParcel = new CryptoInputParcel(); -- cgit v1.2.3 From e14a2efcaded63ee6d0946d46a605c858941e3ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 10 May 2015 03:31:19 +0200 Subject: Fixes and clarifications to app signature (or better certificate) pinning --- .../keychain/provider/KeychainContract.java | 2 +- .../keychain/provider/KeychainDatabase.java | 2 +- .../keychain/provider/ProviderHelper.java | 9 ++- .../keychain/remote/RemoteService.java | 75 +++++++++++++--------- 4 files changed, 50 insertions(+), 38 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index 6af5f4217..d5283f01f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -73,7 +73,7 @@ public class KeychainContract { interface ApiAppsColumns { String PACKAGE_NAME = "package_name"; - String PACKAGE_SIGNATURE = "package_signature"; + String PACKAGE_CERTIFICATE = "package_signature"; } interface ApiAppsAccountsColumns { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 4a162989f..ff661e494 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -148,7 +148,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + ApiAppsColumns.PACKAGE_NAME + " TEXT NOT NULL UNIQUE, " - + ApiAppsColumns.PACKAGE_SIGNATURE + " BLOB" + + ApiAppsColumns.PACKAGE_CERTIFICATE + " BLOB" + ")"; private static final String CREATE_API_APPS_ACCOUNTS = diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 1d3934620..1cd1826a3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -45,7 +45,6 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.PgpConstants; -import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedPublicKey; @@ -1415,7 +1414,7 @@ public class ProviderHelper { private ContentValues contentValueForApiApps(AppSettings appSettings) { ContentValues values = new ContentValues(); values.put(ApiApps.PACKAGE_NAME, appSettings.getPackageName()); - values.put(ApiApps.PACKAGE_SIGNATURE, appSettings.getPackageSignature()); + values.put(ApiApps.PACKAGE_CERTIFICATE, appSettings.getPackageSignature()); return values; } @@ -1462,7 +1461,7 @@ public class ProviderHelper { settings.setPackageName(cursor.getString( cursor.getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME))); settings.setPackageSignature(cursor.getBlob( - cursor.getColumnIndex(KeychainContract.ApiApps.PACKAGE_SIGNATURE))); + cursor.getColumnIndex(KeychainContract.ApiApps.PACKAGE_CERTIFICATE))); } } finally { if (cursor != null) { @@ -1575,10 +1574,10 @@ public class ProviderHelper { return fingerprints; } - public byte[] getApiAppSignature(String packageName) { + public byte[] getApiAppCertificate(String packageName) { Uri queryUri = ApiApps.buildByPackageNameUri(packageName); - String[] projection = new String[]{ApiApps.PACKAGE_SIGNATURE}; + String[] projection = new String[]{ApiApps.PACKAGE_CERTIFICATE}; Cursor cursor = mContentResolver.query(queryUri, projection, null, null, null); try { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java index 59dafb505..e4d4ac49a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java @@ -37,6 +37,8 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity; import org.sufficientlysecure.keychain.util.Log; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -45,10 +47,10 @@ import java.util.Arrays; */ public abstract class RemoteService extends Service { - public static class WrongPackageSignatureException extends Exception { + public static class WrongPackageCertificateException extends Exception { private static final long serialVersionUID = -8294642703122196028L; - public WrongPackageSignatureException(String message) { + public WrongPackageCertificateException(String message) { super(message); } } @@ -74,9 +76,9 @@ public abstract class RemoteService extends Service { String packageName = getCurrentCallingPackage(); Log.d(Constants.TAG, "isAllowed packageName: " + packageName); - byte[] packageSignature; + byte[] packageCertificate; try { - packageSignature = getPackageSignature(packageName); + packageCertificate = getPackageCertificate(packageName); } catch (NameNotFoundException e) { Log.e(Constants.TAG, "Should not happen, returning!", e); // return error @@ -91,7 +93,7 @@ public abstract class RemoteService extends Service { 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_PACKAGE_SIGNATURE, packageCertificate); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, @@ -105,7 +107,7 @@ public abstract class RemoteService extends Service { return result; } - } catch (WrongPackageSignatureException e) { + } catch (WrongPackageCertificateException e) { Log.e(Constants.TAG, "wrong signature!", e); Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); @@ -127,14 +129,24 @@ public abstract class RemoteService extends Service { } } - private byte[] getPackageSignature(String packageName) throws NameNotFoundException { + private byte[] getPackageCertificate(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(); + // NOTE: Silly Android API naming: Signatures are actually certificates + Signature[] certificates = pkgInfo.signatures; + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + for (Signature cert : certificates) { + try { + outputStream.write(cert.toByteArray()); + } catch (IOException e) { + throw new RuntimeException("Should not happen! Writing ByteArrayOutputStream to concat certificates failed"); + } + } - return packageSignature; + // Even if an apk has several certificates, these certificates should never change + // Google Play does not allow the introduction of new certificates into an existing apk + // Also see this attack: http://stackoverflow.com/a/10567852 + return outputStream.toByteArray(); } /** @@ -144,9 +156,12 @@ public abstract class RemoteService extends Service { * @return package name */ protected String getCurrentCallingPackage() { - // TODO: - // callingPackages contains more than one entry when sharedUserId has been used... String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid()); + + // NOTE: No support for sharedUserIds + // callingPackages contains more than one entry when sharedUserId has been used + // No plans to support sharedUserIds due to many bugs connected to them: + // http://java-hamster.blogspot.de/2010/05/androids-shareduserid.html String currentPkg = callingPackages[0]; Log.d(Constants.TAG, "currentPkg: " + currentPkg); @@ -155,12 +170,12 @@ public abstract class RemoteService extends Service { /** * DEPRECATED API - * + *

* Retrieves AccountSettings from database for the application calling this remote service */ protected AccountSettings getAccSettings(String accountName) { String currentPkg = getCurrentCallingPackage(); - Log.d(Constants.TAG, "getAccSettings accountName: "+ accountName); + Log.d(Constants.TAG, "getAccSettings accountName: " + accountName); Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(currentPkg, accountName); @@ -198,14 +213,14 @@ public abstract class RemoteService extends Service { * * @param allowOnlySelf allow only Keychain app itself * @return true if process is allowed to use this service - * @throws WrongPackageSignatureException + * @throws WrongPackageCertificateException */ - private boolean isCallerAllowed(boolean allowOnlySelf) throws WrongPackageSignatureException { + private boolean isCallerAllowed(boolean allowOnlySelf) throws WrongPackageCertificateException { return isUidAllowed(Binder.getCallingUid(), allowOnlySelf); } private boolean isUidAllowed(int uid, boolean allowOnlySelf) - throws WrongPackageSignatureException { + throws WrongPackageCertificateException { if (android.os.Process.myUid() == uid) { return true; } @@ -229,11 +244,9 @@ public abstract class RemoteService extends Service { /** * Checks if packageName is a registered app for the API. Does not return true for own package! * - * @param packageName - * @return - * @throws WrongPackageSignatureException + * @throws WrongPackageCertificateException */ - private boolean isPackageAllowed(String packageName) throws WrongPackageSignatureException { + private boolean isPackageAllowed(String packageName) throws WrongPackageCertificateException { Log.d(Constants.TAG, "isPackageAllowed packageName: " + packageName); ArrayList allowedPkgs = mProviderHelper.getRegisteredApiApps(); @@ -244,22 +257,22 @@ public abstract class RemoteService extends Service { Log.d(Constants.TAG, "Package is allowed! packageName: " + packageName); // check package signature - byte[] currentSig; + byte[] currentCert; try { - currentSig = getPackageSignature(packageName); + currentCert = getPackageCertificate(packageName); } catch (NameNotFoundException e) { - throw new WrongPackageSignatureException(e.getMessage()); + throw new WrongPackageCertificateException(e.getMessage()); } - byte[] storedSig = mProviderHelper.getApiAppSignature(packageName); - if (Arrays.equals(currentSig, storedSig)) { + byte[] storedCert = mProviderHelper.getApiAppCertificate(packageName); + if (Arrays.equals(currentCert, storedCert)) { Log.d(Constants.TAG, - "Package signature is correct! (equals signature from database)"); + "Package certificate is correct! (equals certificate from database)"); return true; } else { - throw new WrongPackageSignatureException( - "PACKAGE NOT ALLOWED! Signature wrong! (Signature not " + - "equals signature from database)"); + throw new WrongPackageCertificateException( + "PACKAGE NOT ALLOWED! Certificate wrong! (Certificate not " + + "equals certificate from database)"); } } -- cgit v1.2.3 From 0a29f6d3acdb36e8e27640624634edcaea7fb8e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 10 May 2015 11:52:39 +0200 Subject: Cleanup --- .../keychain/provider/ProviderHelper.java | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 1cd1826a3..33e9a4345 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -1553,27 +1553,6 @@ public class ProviderHelper { mContentResolver.insert(uri, values); } - public Set getAllFingerprints(Uri uri) { - Set fingerprints = new HashSet<>(); - String[] projection = new String[]{KeyRings.FINGERPRINT}; - Cursor cursor = mContentResolver.query(uri, projection, null, null, null); - try { - if (cursor != null) { - int fingerprintColumn = cursor.getColumnIndex(KeyRings.FINGERPRINT); - while (cursor.moveToNext()) { - fingerprints.add( - KeyFormattingUtils.convertFingerprintToHex(cursor.getBlob(fingerprintColumn)) - ); - } - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - return fingerprints; - } - public byte[] getApiAppCertificate(String packageName) { Uri queryUri = ApiApps.buildByPackageNameUri(packageName); -- cgit v1.2.3 From e4b7920edcc04bed6524929b85ef1acb2c6a01d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 10 May 2015 12:11:35 +0200 Subject: Fix crash with v3 key fingerprints --- .../keychain/ui/util/KeyFormattingUtils.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java index 91a7d361a..2dea885a7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java @@ -216,7 +216,16 @@ public class KeyFormattingUtils { * @return */ public static String convertFingerprintToHex(byte[] fingerprint) { - return Hex.toHexString(fingerprint, 0, 20).toLowerCase(Locale.ENGLISH); + // NOTE: Even though v3 keys are not imported we need to support both fingerprints for + // display/comparison before import + // Also better cut of unneeded parts, e.g., for fingerprints returned from YubiKeys + if (fingerprint.length < 20) { + // v3 key fingerprint with 128 bit (MD5) + return Hex.toHexString(fingerprint, 0, 16).toLowerCase(Locale.ENGLISH); + } else { + // v4 key fingerprint with 160 bit (SHA1) + return Hex.toHexString(fingerprint, 0, 20).toLowerCase(Locale.ENGLISH); + } } public static long getKeyIdFromFingerprint(byte[] fingerprint) { -- cgit v1.2.3 From a35594201a7b96d091b0a1a7ef46fb90ff5e0bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 10 May 2015 13:16:03 +0200 Subject: Fixing rotate crashes in create key --- .../sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java | 6 +----- .../keychain/ui/dialog/ProgressDialogFragment.java | 8 ++++---- 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index dbff4fb9f..597f04d6b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -48,7 +48,7 @@ import java.util.regex.Pattern; public class CreateKeyEmailFragment extends Fragment { private CreateKeyActivity mCreateKeyActivity; private EmailEditText mEmailEdit; - private ArrayList mAdditionalEmailModels; + private ArrayList mAdditionalEmailModels = new ArrayList<>(); private EmailAdapter mEmailAdapter; // NOTE: Do not use more complicated pattern like defined in android.util.Patterns.EMAIL_ADDRESS @@ -119,10 +119,6 @@ public class CreateKeyEmailFragment extends Fragment { emailsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); emailsRecyclerView.setItemAnimator(new DefaultItemAnimator()); - // initial values - if (mAdditionalEmailModels == null) { - mAdditionalEmailModels = new ArrayList<>(); - } if (mEmailAdapter == null) { mEmailAdapter = new EmailAdapter(mAdditionalEmailModels, new View.OnClickListener() { @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java index b58f584c8..545500cd4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java @@ -94,12 +94,12 @@ public class ProgressDialogFragment extends DialogFragment { /** Updates progress of dialog */ public void setProgress(String message, int progress, int max) { - if (mIsCancelled) { - return; - } - ProgressDialog dialog = (ProgressDialog) getDialog(); + if (mIsCancelled || dialog == null) { + return; + } + dialog.setMessage(message); dialog.setProgress(progress); dialog.setMax(max); -- cgit v1.2.3 From 5c44f8400970de5943fd6c5e804dfa394f3deb01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 10 May 2015 13:16:37 +0200 Subject: 3.2.1 --- .../sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java index 545500cd4..af9d175ff 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java @@ -99,7 +99,7 @@ public class ProgressDialogFragment extends DialogFragment { if (mIsCancelled || dialog == null) { return; } - + dialog.setMessage(message); dialog.setProgress(progress); dialog.setMax(max); -- cgit v1.2.3