From 774c806f460204505491db47f9481103da187e8d Mon Sep 17 00:00:00 2001 From: Alex Fong Date: Thu, 19 May 2016 12:04:01 +0800 Subject: Added passphrase check for stripped masterkeys --- .../keychain/ui/BackupRestoreFragment.java | 75 ++++++++++++++++------ 1 file changed, 57 insertions(+), 18 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java index 3ff3bfbe3..4a1e4937d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java @@ -17,7 +17,7 @@ package org.sufficientlysecure.keychain.ui; -import java.util.ArrayList; +import java.util.*; import android.app.Activity; import android.content.ContentResolver; @@ -35,17 +35,17 @@ import android.view.ViewGroup; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.FileHelper; public class BackupRestoreFragment extends Fragment { - // This ids for multiple key export. - private ArrayList mIdsForRepeatAskPassphrase; - // This index for remembering the number of master key. - private int mIndex; + // masterKeyId & subKeyId for multi-key export + private Iterator> mIdsForRepeatAskPassphrase; private static final int REQUEST_REPEAT_PASSPHRASE = 0x00007002; private static final int REQUEST_CODE_INPUT = 0x00007003; @@ -93,10 +93,10 @@ public class BackupRestoreFragment extends Fragment { return; } - new AsyncTask>() { + new AsyncTask>() { @Override - protected ArrayList doInBackground(ContentResolver... resolver) { - ArrayList askPassphraseIds = new ArrayList<>(); + protected HashMap doInBackground(ContentResolver... resolver) { + HashMap askPassphraseIds = new HashMap<>(); Cursor cursor = resolver[0].query( KeyRings.buildUnifiedKeyRingsUri(), new String[]{ KeyRings.MASTER_KEY_ID, @@ -109,13 +109,20 @@ public class BackupRestoreFragment extends Fragment { switch (secretKeyType) { // all of these make no sense to ask case PASSPHRASE_EMPTY: - case GNU_DUMMY: case DIVERT_TO_CARD: case UNAVAILABLE: continue; + case GNU_DUMMY: { + Long masterKeyId = cursor.getLong(0); + Long subKeyId = getFirstSubKeyWithPassphrase(masterKeyId, resolver[0]); + if(subKeyId != null) { + askPassphraseIds.put(masterKeyId, subKeyId); + } + continue; + } default: { - long keyId = cursor.getLong(0); - askPassphraseIds.add(keyId); + long masterKeyId = cursor.getLong(0); + askPassphraseIds.put(masterKeyId, masterKeyId); } } } @@ -128,18 +135,48 @@ public class BackupRestoreFragment extends Fragment { return askPassphraseIds; } + private Long getFirstSubKeyWithPassphrase(long masterKeyId, ContentResolver resolver) { + Cursor cursor = resolver.query( + KeychainContract.Keys.buildKeysUri(masterKeyId), new String[]{ + Keys.KEY_ID, + Keys.HAS_SECRET, + }, Keys.HAS_SECRET + " != 0", null, null); + try { + if (cursor != null) { + while(cursor.moveToNext()) { + SecretKeyType secretKeyType = SecretKeyType.fromNum(cursor.getInt(1)); + switch (secretKeyType) { + case PASSPHRASE_EMPTY: + case DIVERT_TO_CARD: + case UNAVAILABLE: + return null; + case GNU_DUMMY: + continue; + default: { + return cursor.getLong(0); + } + } + } + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + return null; + } + @Override - protected void onPostExecute(ArrayList askPassphraseIds) { + protected void onPostExecute(HashMap askPassphraseIds) { super.onPostExecute(askPassphraseIds); FragmentActivity activity = getActivity(); if (activity == null) { return; } - mIdsForRepeatAskPassphrase = askPassphraseIds; - mIndex = 0; + mIdsForRepeatAskPassphrase = askPassphraseIds.entrySet().iterator(); - if (mIdsForRepeatAskPassphrase.size() != 0) { + if (mIdsForRepeatAskPassphrase.hasNext()) { startPassphraseActivity(); return; } @@ -157,9 +194,11 @@ public class BackupRestoreFragment extends Fragment { } Intent intent = new Intent(activity, PassphraseDialogActivity.class); - long masterKeyId = mIdsForRepeatAskPassphrase.get(mIndex++); + Map.Entry keyPair = mIdsForRepeatAskPassphrase.next(); + long masterKeyId = keyPair.getKey(); + long subKeyId = keyPair.getValue(); RequiredInputParcel requiredInput = - RequiredInputParcel.createRequiredDecryptPassphrase(masterKeyId, masterKeyId); + RequiredInputParcel.createRequiredDecryptPassphrase(masterKeyId, subKeyId); requiredInput.mSkipCaching = true; intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput); startActivityForResult(intent, REQUEST_REPEAT_PASSPHRASE); @@ -172,7 +211,7 @@ public class BackupRestoreFragment extends Fragment { if (resultCode != Activity.RESULT_OK) { return; } - if (mIndex < mIdsForRepeatAskPassphrase.size()) { + if (mIdsForRepeatAskPassphrase.hasNext()) { startPassphraseActivity(); return; } -- cgit v1.2.3 From 21430c0b49ed9bd573a3c8d2182e4e63494bcf44 Mon Sep 17 00:00:00 2001 From: Alex Fong Date: Thu, 19 May 2016 14:27:55 +0800 Subject: Removed * import --- .../org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java index 4a1e4937d..81198fdb3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java @@ -17,7 +17,9 @@ package org.sufficientlysecure.keychain.ui; -import java.util.*; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import android.app.Activity; import android.content.ContentResolver; -- cgit v1.2.3 From c97d74b3706ca2ffdb54725d1c03f47d2bc2aec9 Mon Sep 17 00:00:00 2001 From: Alex Fong Date: Thu, 19 May 2016 16:48:56 +0800 Subject: Changed HashMap to ArrayList --- .../keychain/ui/BackupRestoreFragment.java | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java index 81198fdb3..e8c4196f2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java @@ -17,9 +17,8 @@ package org.sufficientlysecure.keychain.ui; -import java.util.HashMap; +import java.util.ArrayList; import java.util.Iterator; -import java.util.Map; import android.app.Activity; import android.content.ContentResolver; @@ -31,6 +30,7 @@ import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; +import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -47,7 +47,7 @@ import org.sufficientlysecure.keychain.util.FileHelper; public class BackupRestoreFragment extends Fragment { // masterKeyId & subKeyId for multi-key export - private Iterator> mIdsForRepeatAskPassphrase; + private Iterator> mIdsForRepeatAskPassphrase; private static final int REQUEST_REPEAT_PASSPHRASE = 0x00007002; private static final int REQUEST_CODE_INPUT = 0x00007003; @@ -95,10 +95,10 @@ public class BackupRestoreFragment extends Fragment { return; } - new AsyncTask>() { + new AsyncTask>>() { @Override - protected HashMap doInBackground(ContentResolver... resolver) { - HashMap askPassphraseIds = new HashMap<>(); + protected ArrayList> doInBackground(ContentResolver... resolver) { + ArrayList> askPassphraseIds = new ArrayList<>(); Cursor cursor = resolver[0].query( KeyRings.buildUnifiedKeyRingsUri(), new String[]{ KeyRings.MASTER_KEY_ID, @@ -118,13 +118,13 @@ public class BackupRestoreFragment extends Fragment { Long masterKeyId = cursor.getLong(0); Long subKeyId = getFirstSubKeyWithPassphrase(masterKeyId, resolver[0]); if(subKeyId != null) { - askPassphraseIds.put(masterKeyId, subKeyId); + askPassphraseIds.add(new Pair<>(masterKeyId, subKeyId)); } continue; } default: { long masterKeyId = cursor.getLong(0); - askPassphraseIds.put(masterKeyId, masterKeyId); + askPassphraseIds.add(new Pair<>(masterKeyId, masterKeyId)); } } } @@ -169,14 +169,14 @@ public class BackupRestoreFragment extends Fragment { } @Override - protected void onPostExecute(HashMap askPassphraseIds) { + protected void onPostExecute(ArrayList> askPassphraseIds) { super.onPostExecute(askPassphraseIds); FragmentActivity activity = getActivity(); if (activity == null) { return; } - mIdsForRepeatAskPassphrase = askPassphraseIds.entrySet().iterator(); + mIdsForRepeatAskPassphrase = askPassphraseIds.iterator(); if (mIdsForRepeatAskPassphrase.hasNext()) { startPassphraseActivity(); @@ -196,9 +196,9 @@ public class BackupRestoreFragment extends Fragment { } Intent intent = new Intent(activity, PassphraseDialogActivity.class); - Map.Entry keyPair = mIdsForRepeatAskPassphrase.next(); - long masterKeyId = keyPair.getKey(); - long subKeyId = keyPair.getValue(); + Pair keyPair = mIdsForRepeatAskPassphrase.next(); + long masterKeyId = keyPair.first; + long subKeyId = keyPair.second; RequiredInputParcel requiredInput = RequiredInputParcel.createRequiredDecryptPassphrase(masterKeyId, subKeyId); requiredInput.mSkipCaching = true; -- cgit v1.2.3