diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2016-05-20 15:44:10 +0300 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2016-05-20 15:44:10 +0300 |
commit | 5c924861a05f9616bff1dc6abed14bae80f9d5ce (patch) | |
tree | 25c458a9b6c578b179e1759744f4204ffd72ffd1 | |
parent | df8081012fd412e72535fc687d8b52a225b68ba4 (diff) | |
parent | c97d74b3706ca2ffdb54725d1c03f47d2bc2aec9 (diff) | |
download | open-keychain-5c924861a05f9616bff1dc6abed14bae80f9d5ce.tar.gz open-keychain-5c924861a05f9616bff1dc6abed14bae80f9d5ce.tar.bz2 open-keychain-5c924861a05f9616bff1dc6abed14bae80f9d5ce.zip |
Merge pull request #1875 from AlexFJW/BackupWithStrippedMasterkey
Added passphrase check for stripped masterkeys
-rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java | 75 |
1 files changed, 58 insertions, 17 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..e8c4196f2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupRestoreFragment.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui; import java.util.ArrayList; +import java.util.Iterator; import android.app.Activity; import android.content.ContentResolver; @@ -29,23 +30,24 @@ 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; 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<Pair<Long, Long>> mIdsForRepeatAskPassphrase; private static final int REQUEST_REPEAT_PASSPHRASE = 0x00007002; private static final int REQUEST_CODE_INPUT = 0x00007003; @@ -93,10 +95,10 @@ public class BackupRestoreFragment extends Fragment { return; } - new AsyncTask<ContentResolver, Void, ArrayList<Long>>() { + new AsyncTask<ContentResolver, Void, ArrayList<Pair<Long, Long>>>() { @Override - protected ArrayList<Long> doInBackground(ContentResolver... resolver) { - ArrayList<Long> askPassphraseIds = new ArrayList<>(); + protected ArrayList<Pair<Long,Long>> doInBackground(ContentResolver... resolver) { + ArrayList<Pair<Long, Long>> askPassphraseIds = new ArrayList<>(); Cursor cursor = resolver[0].query( KeyRings.buildUnifiedKeyRingsUri(), new String[]{ KeyRings.MASTER_KEY_ID, @@ -109,13 +111,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.add(new Pair<>(masterKeyId, subKeyId)); + } + continue; + } default: { - long keyId = cursor.getLong(0); - askPassphraseIds.add(keyId); + long masterKeyId = cursor.getLong(0); + askPassphraseIds.add(new Pair<>(masterKeyId, masterKeyId)); } } } @@ -128,18 +137,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(ArrayList<Pair<Long, Long>> askPassphraseIds) { super.onPostExecute(askPassphraseIds); FragmentActivity activity = getActivity(); if (activity == null) { return; } - mIdsForRepeatAskPassphrase = askPassphraseIds; - mIndex = 0; + mIdsForRepeatAskPassphrase = askPassphraseIds.iterator(); - if (mIdsForRepeatAskPassphrase.size() != 0) { + if (mIdsForRepeatAskPassphrase.hasNext()) { startPassphraseActivity(); return; } @@ -157,9 +196,11 @@ public class BackupRestoreFragment extends Fragment { } Intent intent = new Intent(activity, PassphraseDialogActivity.class); - long masterKeyId = mIdsForRepeatAskPassphrase.get(mIndex++); + Pair<Long, Long> keyPair = mIdsForRepeatAskPassphrase.next(); + long masterKeyId = keyPair.first; + long subKeyId = keyPair.second; 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 +213,7 @@ public class BackupRestoreFragment extends Fragment { if (resultCode != Activity.RESULT_OK) { return; } - if (mIndex < mIdsForRepeatAskPassphrase.size()) { + if (mIdsForRepeatAskPassphrase.hasNext()) { startPassphraseActivity(); return; } |