diff options
author | Alex Fong <alexfongg@gmail.com> | 2016-05-19 12:04:01 +0800 |
---|---|---|
committer | Alex Fong <alexfongg@gmail.com> | 2016-05-19 13:08:10 +0800 |
commit | 774c806f460204505491db47f9481103da187e8d (patch) | |
tree | 10e5be28bd7dc1a9499807b7a4cc24912bc1e626 /OpenKeychain/src/main | |
parent | e292ec0d1a53b48a8acc88de4315512783720e99 (diff) | |
download | open-keychain-774c806f460204505491db47f9481103da187e8d.tar.gz open-keychain-774c806f460204505491db47f9481103da187e8d.tar.bz2 open-keychain-774c806f460204505491db47f9481103da187e8d.zip |
Added passphrase check for stripped masterkeys
Diffstat (limited to 'OpenKeychain/src/main')
-rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java | 75 |
1 files 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<Long> mIdsForRepeatAskPassphrase; - // This index for remembering the number of master key. - private int mIndex; + // masterKeyId & subKeyId for multi-key export + private Iterator<Map.Entry<Long, Long>> 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<ContentResolver, Void, ArrayList<Long>>() { + new AsyncTask<ContentResolver, Void, HashMap<Long, Long>>() { @Override - protected ArrayList<Long> doInBackground(ContentResolver... resolver) { - ArrayList<Long> askPassphraseIds = new ArrayList<>(); + protected HashMap<Long, Long> doInBackground(ContentResolver... resolver) { + HashMap<Long, Long> 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<Long> askPassphraseIds) { + protected void onPostExecute(HashMap<Long, Long> 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<Long, Long> 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; } |