diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui')
18 files changed, 255 insertions, 320 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index bd12a3b52..6c74818a5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -43,7 +43,6 @@ import android.widget.TextView; import com.devspark.appmsg.AppMsg; -import org.spongycastle.openpgp.PGPPublicKeyRing; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.Preferences; @@ -51,7 +50,6 @@ import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; -import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.PassphraseCacheService; @@ -222,54 +220,22 @@ public class CertifyKeyActivity extends ActionBarActivity implements * handles the UI bits of the signing process on the UI thread */ private void initiateSigning() { - try { - PGPPublicKeyRing pubring = new ProviderHelper(this).getPGPPublicKeyRing(mPubKeyId); - - // if we have already signed this key, dont bother doing it again - boolean alreadySigned = false; - - /* todo: reconsider this at a later point when certs are in the db - @SuppressWarnings("unchecked") - Iterator<PGPSignature> itr = pubring.getPublicKey(mPubKeyId).getSignatures(); - while (itr.hasNext()) { - PGPSignature sig = itr.next(); - if (sig.getKeyID() == mMasterKeyId) { - alreadySigned = true; - break; - } - } - */ - - if (!alreadySigned) { - /* - * get the user's passphrase for this key (if required) - */ - String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId); - if (passphrase == null) { - PassphraseDialogFragment.show(this, mMasterKeyId, - new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - startSigning(); - } - } + // get the user's passphrase for this key (if required) + String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId); + if (passphrase == null) { + PassphraseDialogFragment.show(this, mMasterKeyId, + new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + startSigning(); } - ); - // bail out; need to wait until the user has entered the passphrase before trying again - return; - } else { - startSigning(); - } - } else { - AppMsg.makeText(this, R.string.key_has_already_been_certified, AppMsg.STYLE_ALERT) - .show(); - - setResult(RESULT_CANCELED); - finish(); - } - } catch (ProviderHelper.NotFoundException e) { - Log.e(Constants.TAG, "key not found!", e); + } + }); + // bail out; need to wait until the user has entered the passphrase before trying again + return; + } else { + startSigning(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index bd3a98567..d9c7a1736 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -19,7 +19,6 @@ package org.sufficientlysecure.keychain.ui; import android.app.Activity; -import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; @@ -44,21 +43,22 @@ import android.widget.Toast; import com.beardedhen.androidbootstrap.BootstrapButton; import com.devspark.appmsg.AppMsg; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.helper.ExportHelper; +import org.sufficientlysecure.keychain.pgp.WrappedSecretKey; +import org.sufficientlysecure.keychain.pgp.WrappedSecretKeyRing; import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.pgp.UncachedSecretKey; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.service.OldSaveKeyringParcel; import org.sufficientlysecure.keychain.service.PassphraseCacheService; -import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; @@ -67,7 +67,6 @@ import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener; import org.sufficientlysecure.keychain.ui.widget.KeyEditor; import org.sufficientlysecure.keychain.ui.widget.SectionView; import org.sufficientlysecure.keychain.ui.widget.UserIdEditor; -import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; import java.util.ArrayList; @@ -89,8 +88,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener // EDIT private Uri mDataUri; - private PGPSecretKeyRing mKeyRing = null; - private SectionView mUserIdsView; private SectionView mKeysView; @@ -106,7 +103,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener private CheckBox mNoPassphrase; Vector<String> mUserIds; - Vector<PGPSecretKey> mKeys; + Vector<UncachedSecretKey> mKeys; Vector<Integer> mKeysUsages; boolean mMasterCanSign = true; @@ -159,7 +156,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener ); mUserIds = new Vector<String>(); - mKeys = new Vector<PGPSecretKey>(); + mKeys = new Vector<UncachedSecretKey>(); mKeysUsages = new Vector<Integer>(); // Catch Intents opened from other apps @@ -240,7 +237,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener // get new key from data bundle returned from service Bundle data = message.getData(); - ArrayList<PGPSecretKey> newKeys = + ArrayList<UncachedSecretKey> newKeys = PgpConversionHelper.BytesToPGPSecretKeyList(data .getByteArray(KeychainIntentService.RESULT_NEW_KEY)); @@ -288,18 +285,18 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener Log.d(Constants.TAG, "uri: " + mDataUri); try { - Uri secretUri = KeychainContract.KeyRingData.buildSecretKeyRingUri(mDataUri); - mKeyRing = (PGPSecretKeyRing) new ProviderHelper(this).getPGPKeyRing(secretUri); - - PGPSecretKey masterKey = mKeyRing.getSecretKey(); - mMasterCanSign = PgpKeyHelper.isCertificationKey(mKeyRing.getSecretKey()); - for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(mKeyRing.getSecretKeys())) { - mKeys.add(key); - mKeysUsages.add(-1); // get usage when view is created + Uri secretUri = KeyRings.buildUnifiedKeyRingUri(mDataUri); + WrappedSecretKeyRing keyRing = new ProviderHelper(this).getWrappedSecretKeyRing(secretUri); + + mMasterCanSign = keyRing.getSubKey().canCertify(); + for (WrappedSecretKey key : keyRing.iterator()) { + // Turn into uncached instance + mKeys.add(key.getUncached()); + mKeysUsages.add(key.getKeyUsage()); // get usage when view is created } boolean isSet = false; - for (String userId : new IterableIterator<String>(masterKey.getUserIDs())) { + for (String userId : keyRing.getSubKey().getUserIds()) { Log.d(Constants.TAG, "Added userId " + userId); if (!isSet) { isSet = true; @@ -314,7 +311,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener buildLayout(false); mCurrentPassphrase = ""; - mIsPassphraseSet = PassphraseCacheService.hasPassphrase(mKeyRing); + mIsPassphraseSet = keyRing.hasPassphrase(); if (!mIsPassphraseSet) { // check "no passphrase" checkbox and remove button mNoPassphrase.setChecked(true); @@ -432,7 +429,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener if (mKeysView.getEditors().getChildCount() == 0) { return 0; } - return ((KeyEditor) mKeysView.getEditors().getChildAt(0)).getValue().getKeyID(); + return ((KeyEditor) mKeysView.getEditors().getChildAt(0)).getValue().getKeyId(); } public boolean isPassphraseSet() { @@ -556,7 +553,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING); - SaveKeyringParcel saveParams = new SaveKeyringParcel(); + OldSaveKeyringParcel saveParams = new OldSaveKeyringParcel(); saveParams.userIds = getUserIds(mUserIdsView); saveParams.originalIDs = mUserIdsView.getOriginalIDs(); saveParams.deletedIDs = mUserIdsView.getDeletedIDs(); @@ -572,7 +569,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener saveParams.keys = getKeys(mKeysView); saveParams.originalPrimaryID = mUserIdsView.getOriginalPrimaryID(); - // fill values for this action Bundle data = new Bundle(); data.putBoolean(KeychainIntentService.SAVE_KEYRING_CAN_SIGN, mMasterCanSign); @@ -591,8 +587,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener Intent data = new Intent(); // return uri pointing to new created key - Uri uri = KeychainContract.KeyRings.buildGenericKeyRingUri( - String.valueOf(getMasterKeyId())); + Uri uri = KeyRings.buildGenericKeyRingUri(getMasterKeyId()); data.setData(uri); setResult(RESULT_OK, data); @@ -690,8 +685,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener * @param keysView * @return */ - private ArrayList<PGPSecretKey> getKeys(SectionView keysView) throws PgpGeneralException { - ArrayList<PGPSecretKey> keys = new ArrayList<PGPSecretKey>(); + private ArrayList<UncachedSecretKey> getKeys(SectionView keysView) throws PgpGeneralException { + ArrayList<UncachedSecretKey> keys = new ArrayList<UncachedSecretKey>(); ViewGroup keyEditors = keysView.getEditors(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index c954e6465..03483575c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -30,11 +30,11 @@ import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.Log; @@ -144,20 +144,17 @@ public class EncryptAsymmetricFragment extends Fragment { */ private void preselectKeys(long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds, ProviderHelper providerHelper) { + // TODO all of this works under the assumption that the first suitable subkey is always used! + // not sure if we need to distinguish between different subkeys here? if (preselectedSignatureKeyId != 0) { - // TODO: don't use bouncy castle objects! try { - PGPSecretKeyRing keyRing = providerHelper.getPGPSecretKeyRingWithKeyId( - preselectedSignatureKeyId); - - PGPSecretKey masterKey = keyRing.getSecretKey(); - if (masterKey != null) { - PGPSecretKey signKey = PgpKeyHelper.getFirstSigningSubkey(keyRing); - if (signKey != null) { - setSignatureKeyId(masterKey.getKeyID()); - } + CachedPublicKeyRing keyring = + providerHelper.getCachedPublicKeyRing( + KeyRings.buildUnifiedKeyRingUri(preselectedSignatureKeyId)); + if(keyring.hasAnySecret()) { + setSignatureKeyId(keyring.getMasterKeyId()); } - } catch (ProviderHelper.NotFoundException e) { + } catch (PgpGeneralException e) { Log.e(Constants.TAG, "key not found!", e); } } @@ -165,14 +162,13 @@ public class EncryptAsymmetricFragment extends Fragment { if (preselectedEncryptionKeyIds != null) { Vector<Long> goodIds = new Vector<Long>(); for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) { - // TODO One query per selected key?! wtf try { - long id = providerHelper.getMasterKeyId( + long id = providerHelper.getCachedPublicKeyRing( KeyRings.buildUnifiedKeyRingsFindBySubkeyUri( - Long.toString(preselectedEncryptionKeyIds[i])) - ); + preselectedEncryptionKeyIds[i]) + ).getMasterKeyId(); goodIds.add(id); - } catch (ProviderHelper.NotFoundException e) { + } catch (PgpGeneralException e) { Log.e(Constants.TAG, "key not found!", e); } } 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 35076287b..d33d450f9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -42,6 +42,7 @@ import com.devspark.appmsg.AppMsg; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; @@ -415,8 +416,8 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O // fill values for this action Bundle data = new Bundle(); - // get selected key entries - ArrayList<ImportKeysListEntry> selectedEntries = mListFragment.getSelectedData(); + // get DATA from selected key entries + ArrayList<ParcelableKeyRing> selectedEntries = mListFragment.getSelectedData(); data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, selectedEntries); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); @@ -442,7 +443,7 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O data.putString(KeychainIntentService.DOWNLOAD_KEY_SERVER, mListFragment.getKeyServer()); // get selected key entries - ArrayList<ImportKeysListEntry> selectedEntries = mListFragment.getSelectedData(); + ArrayList<ImportKeysListEntry> selectedEntries = mListFragment.getSelectedEntries(); data.putParcelableArrayList(KeychainIntentService.DOWNLOAD_KEY_LIST, selectedEntries); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); @@ -466,7 +467,7 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O Bundle data = new Bundle(); // get selected key entries - ArrayList<ImportKeysListEntry> selectedEntries = mListFragment.getSelectedData(); + ArrayList<ImportKeysListEntry> selectedEntries = mListFragment.getSelectedEntries(); data.putParcelableArrayList(KeychainIntentService.DOWNLOAD_KEY_LIST, selectedEntries); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index d9bd9b782..b70dd4d80 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -23,6 +23,7 @@ import android.os.Bundle; import android.support.v4.app.ListFragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; +import android.support.v4.util.LongSparseArray; import android.view.View; import android.widget.ListView; @@ -31,6 +32,7 @@ import com.devspark.appmsg.AppMsg; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.Preferences; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.ui.adapter.AsyncTaskResultWrapper; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; @@ -67,6 +69,8 @@ public class ImportKeysListFragment extends ListFragment implements private static final int LOADER_ID_SERVER_QUERY = 1; private static final int LOADER_ID_KEYBASE = 2; + private LongSparseArray<ParcelableKeyRing> mCachedKeyData; + public byte[] getKeyBytes() { return mKeyBytes; } @@ -91,8 +95,16 @@ public class ImportKeysListFragment extends ListFragment implements return mAdapter.getData(); } - public ArrayList<ImportKeysListEntry> getSelectedData() { - return mAdapter.getSelectedData(); + public ArrayList<ParcelableKeyRing> getSelectedData() { + ArrayList<ParcelableKeyRing> result = new ArrayList<ParcelableKeyRing>(); + for(ImportKeysListEntry entry : getSelectedEntries()) { + result.add(mCachedKeyData.get(entry.getKeyId())); + } + return result; + } + + public ArrayList<ImportKeysListEntry> getSelectedEntries() { + return mAdapter.getSelectedEntries(); } /** @@ -120,8 +132,7 @@ public class ImportKeysListFragment extends ListFragment implements mActivity = getActivity(); - // Give some text to display if there is no data. In a real - // application this would come from a resource. + // Give some text to display if there is no data. setEmptyText(mActivity.getString(R.string.error_nothing_import)); // Create an empty adapter we will use to display the loaded data. @@ -252,11 +263,15 @@ public class ImportKeysListFragment extends ListFragment implements Exception error = data.getError(); + // free old cached key data + mCachedKeyData = null; + switch (loader.getId()) { case LOADER_ID_BYTES: if (error == null) { // No error + mCachedKeyData = ((ImportKeysListLoader) loader).getParcelableRings(); } else if (error instanceof ImportKeysListLoader.FileHasNoContent) { AppMsg.makeText(getActivity(), R.string.error_import_file_no_content, AppMsg.STYLE_ALERT).show(); 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 e38ed6e67..9c90b5eb7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -317,7 +317,7 @@ public class KeyListFragment extends LoaderFragment public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { Intent viewIntent = new Intent(getActivity(), ViewKeyActivity.class); viewIntent.setData( - KeyRings.buildGenericKeyRingUri(Long.toString(mAdapter.getMasterKeyId(position)))); + KeyRings.buildGenericKeyRingUri(mAdapter.getMasterKeyId(position))); startActivity(viewIntent); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java index 38a0c8478..9ddc8e3e1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java @@ -84,7 +84,7 @@ public class SelectSecretKeyFragment extends ListFragment implements @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { long masterKeyId = mAdapter.getMasterKeyId(position); - Uri result = KeyRings.buildGenericKeyRingUri(String.valueOf(masterKeyId)); + Uri result = KeyRings.buildGenericKeyRingUri(masterKeyId); // return data to activity, which results in finishing it mActivity.afterListSelection(result); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java index 8db750917..fe2ecf3a3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java @@ -132,7 +132,7 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan //For AppSettingsFragment public void selectKey(long masterKeyId) { - Uri buildUri = KeychainContract.KeyRings.buildGenericKeyRingUri(String.valueOf(masterKeyId)); + Uri buildUri = KeychainContract.KeyRings.buildGenericKeyRingUri(masterKeyId); mReceivedUri = buildUri; getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java index f78c30820..ae0206ab1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java @@ -32,24 +32,17 @@ import android.view.MenuItem; import android.view.View; import android.widget.TextView; -import org.spongycastle.bcpg.SignatureSubpacket; -import org.spongycastle.bcpg.SignatureSubpacketTags; -import org.spongycastle.bcpg.sig.RevocationReason; -import org.spongycastle.openpgp.PGPException; -import org.spongycastle.openpgp.PGPKeyRing; -import org.spongycastle.openpgp.PGPSignature; -import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; +import org.sufficientlysecure.keychain.pgp.WrappedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.pgp.WrappedSignature; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.Log; -import java.security.SignatureException; import java.util.Date; public class ViewCertActivity extends ActionBarActivity @@ -146,32 +139,25 @@ public class ViewCertActivity extends ActionBarActivity mCertifierUid.setText(R.string.unknown_uid); } - PGPSignature sig = PgpConversionHelper.BytesToPGPSignature(data.getBlob(INDEX_DATA)); + WrappedSignature sig = WrappedSignature.fromBytes(data.getBlob(INDEX_DATA)); try { ProviderHelper providerHelper = new ProviderHelper(this); - PGPKeyRing signeeRing = providerHelper.getPGPKeyRing( - KeychainContract.KeyRingData.buildPublicKeyRingUri( - Long.toString(data.getLong(INDEX_MASTER_KEY_ID))) - ); - PGPKeyRing signerRing = providerHelper.getPGPKeyRing( - KeychainContract.KeyRingData.buildPublicKeyRingUri( - Long.toString(sig.getKeyID())) - ); + + WrappedPublicKeyRing signeeRing = + providerHelper.getWrappedPublicKeyRing(data.getLong(INDEX_MASTER_KEY_ID)); + WrappedPublicKeyRing signerRing = + providerHelper.getWrappedPublicKeyRing(sig.getKeyId()); try { - sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME), signerRing.getPublicKey()); - if (sig.verifyCertification(signeeUid, signeeRing.getPublicKey())) { + sig.init(signerRing.getSubkey()); + if (sig.verifySignature(signeeRing.getSubkey(), signeeUid)) { mStatus.setText(R.string.cert_verify_ok); mStatus.setTextColor(getResources().getColor(R.color.bbutton_success)); } else { mStatus.setText(R.string.cert_verify_failed); mStatus.setTextColor(getResources().getColor(R.color.alert)); } - } catch (SignatureException e) { - mStatus.setText(R.string.cert_verify_error); - mStatus.setTextColor(getResources().getColor(R.color.alert)); - } catch (PGPException e) { + } catch (PgpGeneralException e) { mStatus.setText(R.string.cert_verify_error); mStatus.setTextColor(getResources().getColor(R.color.alert)); } @@ -185,29 +171,26 @@ public class ViewCertActivity extends ActionBarActivity mRowReason.setVisibility(View.GONE); switch (data.getInt(INDEX_TYPE)) { - case PGPSignature.DEFAULT_CERTIFICATION: + case WrappedSignature.DEFAULT_CERTIFICATION: mType.setText(R.string.cert_default); break; - case PGPSignature.NO_CERTIFICATION: + case WrappedSignature.NO_CERTIFICATION: mType.setText(R.string.cert_none); break; - case PGPSignature.CASUAL_CERTIFICATION: + case WrappedSignature.CASUAL_CERTIFICATION: mType.setText(R.string.cert_casual); break; - case PGPSignature.POSITIVE_CERTIFICATION: + case WrappedSignature.POSITIVE_CERTIFICATION: mType.setText(R.string.cert_positive); break; - case PGPSignature.CERTIFICATION_REVOCATION: { + case WrappedSignature.CERTIFICATION_REVOCATION: { mType.setText(R.string.cert_revoke); - if (sig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.REVOCATION_REASON)) { - SignatureSubpacket p = sig.getHashedSubPackets().getSubpacket( - SignatureSubpacketTags.REVOCATION_REASON); - // For some reason, this is missing in SignatureSubpacketInputStream:146 - if (!(p instanceof RevocationReason)) { - p = new RevocationReason(false, p.getData()); + if (sig.isRevocation()) { + try { + mReason.setText(sig.getRevocationReason()); + } catch(PgpGeneralException e) { + mReason.setText(R.string.none); } - String reason = ((RevocationReason) p).getRevocationDescription(); - mReason.setText(reason); mRowReason.setVisibility(View.VISIBLE); } break; @@ -223,14 +206,11 @@ public class ViewCertActivity extends ActionBarActivity try { ProviderHelper providerHelper = new ProviderHelper(ViewCertActivity.this); - long signerMasterKeyId = providerHelper.getMasterKeyId( - KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(mCertifierKeyId)) - ); - viewIntent.setData(KeyRings.buildGenericKeyRingUri( - Long.toString(signerMasterKeyId)) - ); + long signerMasterKeyId = providerHelper.getCachedPublicKeyRing( + KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(mCertifierKeyId)).getMasterKeyId(); + viewIntent.setData(KeyRings.buildGenericKeyRingUri(signerMasterKeyId)); startActivity(viewIntent); - } catch (ProviderHelper.NotFoundException e) { + } catch (PgpGeneralException e) { // TODO notify user of this, maybe offer download? Log.e(Constants.TAG, "key not found!", e); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 8c52e6f22..bed116f5f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -326,10 +326,10 @@ public class ViewKeyActivity extends ActionBarActivity implements try { Uri blobUri = KeychainContract.KeyRingData.buildPublicKeyRingUri(dataUri); - mNfcKeyringBytes = mProviderHelper.getPGPKeyRing( - blobUri).getEncoded(); - } catch (IOException e) { - Log.e(Constants.TAG, "Error parsing keyring", e); + mNfcKeyringBytes = (byte[]) mProviderHelper.getGenericData( + blobUri, + KeychainContract.KeyRingData.KEY_RING_DATA, + ProviderHelper.FIELD_TYPE_BLOB); } catch (ProviderHelper.NotFoundException e) { Log.e(Constants.TAG, "key not found!", e); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java index d5658586d..3cd43638a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java @@ -33,10 +33,10 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.TextView; -import org.spongycastle.openpgp.PGPSignature; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.pgp.WrappedSignature; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.util.Log; @@ -227,19 +227,19 @@ public class ViewKeyCertsFragment extends LoaderFragment wSignerKeyId.setText(signerKeyId); switch (cursor.getInt(mIndexType)) { - case PGPSignature.DEFAULT_CERTIFICATION: // 0x10 + case WrappedSignature.DEFAULT_CERTIFICATION: // 0x10 wSignStatus.setText(R.string.cert_default); break; - case PGPSignature.NO_CERTIFICATION: // 0x11 + case WrappedSignature.NO_CERTIFICATION: // 0x11 wSignStatus.setText(R.string.cert_none); break; - case PGPSignature.CASUAL_CERTIFICATION: // 0x12 + case WrappedSignature.CASUAL_CERTIFICATION: // 0x12 wSignStatus.setText(R.string.cert_casual); break; - case PGPSignature.POSITIVE_CERTIFICATION: // 0x13 + case WrappedSignature.POSITIVE_CERTIFICATION: // 0x13 wSignStatus.setText(R.string.cert_positive); break; - case PGPSignature.CERTIFICATION_REVOCATION: // 0x30 + case WrappedSignature.CERTIFICATION_REVOCATION: // 0x30 wSignStatus.setText(R.string.cert_revoke); break; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index 026417776..c16bb82af 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -32,7 +32,9 @@ import android.widget.ListView; import com.devspark.appmsg.AppMsg; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R;import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.provider.ProviderHelper; @@ -235,14 +237,16 @@ public class ViewKeyMainFragment extends LoaderFragment implements return; } try { - long keyId = new ProviderHelper(getActivity()).extractOrGetMasterKeyId(dataUri); + long keyId = new ProviderHelper(getActivity()) + .getCachedPublicKeyRing(dataUri) + .extractOrGetMasterKeyId(); long[] encryptionKeyIds = new long[]{keyId}; Intent intent = new Intent(getActivity(), EncryptActivity.class); intent.setAction(EncryptActivity.ACTION_ENCRYPT); intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds); // used instead of startActivity set actionbar based on callingPackage startActivityForResult(intent, 0); - } catch (ProviderHelper.NotFoundException e) { + } catch (PgpGeneralException e) { Log.e(Constants.TAG, "key not found!", e); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java index b3655133d..a264a804f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java @@ -41,6 +41,7 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; @@ -190,6 +191,9 @@ public class ViewKeyShareFragment extends LoaderFragment implements } startActivity(Intent.createChooser(sendIntent, title)); } + } catch (PgpGeneralException e) { + Log.e(Constants.TAG, "error processing key!", e); + AppMsg.makeText(getActivity(), R.string.error_key_processing, AppMsg.STYLE_ALERT).show(); } catch (IOException e) { Log.e(Constants.TAG, "error processing key!", e); AppMsg.makeText(getActivity(), R.string.error_key_processing, AppMsg.STYLE_ALERT).show(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 9573efdfe..114c6afae 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -32,6 +32,7 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.util.Highlighter; @@ -83,7 +84,7 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> { return mData; } - public ArrayList<ImportKeysListEntry> getSelectedData() { + public ArrayList<ImportKeysListEntry> getSelectedEntries() { ArrayList<ImportKeysListEntry> selectedData = new ArrayList<ImportKeysListEntry>(); for (ImportKeysListEntry entry : mData) { if (entry.isSelected()) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java index b6c829677..03a82696d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java @@ -19,19 +19,19 @@ package org.sufficientlysecure.keychain.ui.adapter; import android.content.Context; import android.support.v4.content.AsyncTaskLoader; +import android.support.v4.util.LongSparseArray; -import org.spongycastle.openpgp.PGPKeyRing; -import org.spongycastle.openpgp.PGPObjectFactory; -import org.spongycastle.openpgp.PGPUtil; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; +import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.PositionAwareInputStream; import java.io.BufferedInputStream; -import java.io.InputStream; import java.util.ArrayList; +import java.util.List; public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> { @@ -56,6 +56,7 @@ public class ImportKeysListLoader final InputData mInputData; ArrayList<ImportKeysListEntry> mData = new ArrayList<ImportKeysListEntry>(); + LongSparseArray<ParcelableKeyRing> mParcelableRings = new LongSparseArray<ParcelableKeyRing>(); AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> mEntryListWrapper; public ImportKeysListLoader(Context context, InputData inputData) { @@ -107,6 +108,10 @@ public class ImportKeysListLoader super.deliverResult(data); } + public LongSparseArray<ParcelableKeyRing> getParcelableRings() { + return mParcelableRings; + } + /** * Reads all PGPKeyRing objects from input * @@ -116,7 +121,6 @@ public class ImportKeysListLoader private void generateListOfKeyrings(InputData inputData) { boolean isEmpty = true; - int nonPgpCounter = 0; PositionAwareInputStream progressIn = new PositionAwareInputStream( inputData.getInputStream()); @@ -129,28 +133,18 @@ public class ImportKeysListLoader // read all available blocks... (asc files can contain many blocks with BEGIN END) while (bufferedInput.available() > 0) { - isEmpty = false; - InputStream in = PGPUtil.getDecoderStream(bufferedInput); - PGPObjectFactory objectFactory = new PGPObjectFactory(in); - - // go through all objects in this block - Object obj; - while ((obj = objectFactory.nextObject()) != null) { - Log.d(Constants.TAG, "Found class: " + obj.getClass()); - - if (obj instanceof PGPKeyRing) { - PGPKeyRing newKeyring = (PGPKeyRing) obj; - addToData(newKeyring); - } else { - Log.e(Constants.TAG, "Object not recognized as PGPKeyRing!"); - nonPgpCounter++; - } + // todo deal with non-keyring objects? + List<UncachedKeyRing> rings = UncachedKeyRing.fromStream(bufferedInput); + for(UncachedKeyRing key : rings) { + ImportKeysListEntry item = new ImportKeysListEntry(getContext(), key); + mData.add(item); + mParcelableRings.put(key.getMasterKeyId(), new ParcelableKeyRing(key.getEncoded())); + isEmpty = false; } } } catch (Exception e) { Log.e(Constants.TAG, "Exception on parsing key file!", e); mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mData, e); - nonPgpCounter = 0; } if (isEmpty) { @@ -158,16 +152,6 @@ public class ImportKeysListLoader mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> (mData, new FileHasNoContent()); } - - if (nonPgpCounter > 0) { - mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> - (mData, new NonPgpPart(nonPgpCounter)); - } - } - - private void addToData(PGPKeyRing keyring) { - ImportKeysListEntry item = new ImportKeysListEntry(getContext(), keyring); - mData.add(item); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java index 12fd77141..5f47ee13c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java @@ -41,17 +41,12 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import android.widget.Toast; -import org.spongycastle.openpgp.PGPException; -import org.spongycastle.openpgp.PGPPrivateKey; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; -import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.pgp.WrappedSecretKey; +import org.sufficientlysecure.keychain.pgp.WrappedSecretKeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.util.Log; @@ -106,8 +101,12 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor long secretKeyId) throws PgpGeneralException { // check if secret key has a passphrase if (!(secretKeyId == Constants.key.symmetric || secretKeyId == Constants.key.none)) { - if (!PassphraseCacheService.hasPassphrase(context, secretKeyId)) { - throw new PgpGeneralException("No passphrase! No passphrase dialog needed!"); + try { + if (!new ProviderHelper(context).getWrappedSecretKeyRing(secretKeyId).hasPassphrase()) { + throw new PgpGeneralException("No passphrase! No passphrase dialog needed!"); + } + } catch(ProviderHelper.NotFoundException e) { + throw new PgpGeneralException("Error: Key not found!", e); } } @@ -139,18 +138,24 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor alert.setTitle(R.string.title_authentication); - final PGPSecretKey secretKey; - final String userId; + final WrappedSecretKeyRing secretRing; + String userId; if (secretKeyId == Constants.key.symmetric || secretKeyId == Constants.key.none) { - secretKey = null; alert.setMessage(R.string.passphrase_for_symmetric_encryption); + secretRing = null; } else { try { ProviderHelper helper = new ProviderHelper(activity); - secretKey = helper.getPGPSecretKeyRing(secretKeyId).getSecretKey(); - userId = (String) helper.getUnifiedData(secretKeyId, - KeychainContract.KeyRings.USER_ID, ProviderHelper.FIELD_TYPE_STRING); + secretRing = helper.getWrappedSecretKeyRing(secretKeyId); + // yes the inner try/catch block is necessary, otherwise the final variable + // above can't be statically verified to have been set in all cases because + // the catch clause doesn't return. + try { + userId = secretRing.getPrimaryUserId(); + } catch (PgpGeneralException e) { + userId = null; + } } catch (ProviderHelper.NotFoundException e) { alert.setTitle(R.string.title_key_not_found); alert.setMessage(getString(R.string.key_not_found, secretKeyId)); @@ -179,76 +184,59 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor @Override public void onClick(DialogInterface dialog, int id) { dismiss(); - long curKeyIndex = 1; - boolean keyOK = true; + String passphrase = mPassphraseEditText.getText().toString(); - long keyId; - PGPSecretKey clickSecretKey = secretKey; - - if (clickSecretKey != null) { - while (keyOK) { - if (clickSecretKey != null) { // check again for loop - try { - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - passphrase.toCharArray()); - PGPPrivateKey testKey = clickSecretKey - .extractPrivateKey(keyDecryptor); - if (testKey == null) { - if (!clickSecretKey.isMasterKey()) { - Toast.makeText(activity, - R.string.error_could_not_extract_private_key, - Toast.LENGTH_SHORT).show(); - - sendMessageToHandler(MESSAGE_CANCEL); - return; - } else { - try { - clickSecretKey = PgpKeyHelper.getKeyNum(new ProviderHelper(activity) - .getPGPSecretKeyRingWithKeyId(secretKeyId), - curKeyIndex - ); - } catch (ProviderHelper.NotFoundException e) { - Log.e(Constants.TAG, "key not found!", e); - } - curKeyIndex++; // does post-increment work like C? - continue; - } - } else { - keyOK = false; - } - } catch (PGPException e) { - Toast.makeText(activity, R.string.wrong_passphrase, - Toast.LENGTH_SHORT).show(); - - sendMessageToHandler(MESSAGE_CANCEL); - return; - } - } else { - Toast.makeText(activity, R.string.error_could_not_extract_private_key, - Toast.LENGTH_SHORT).show(); - - sendMessageToHandler(MESSAGE_CANCEL); - return; // ran out of keys to try + + // Early breakout if we are dealing with a symmetric key + if (secretRing == null) { + PassphraseCacheService.addCachedPassphrase(activity, Constants.key.symmetric, passphrase); + // also return passphrase back to activity + Bundle data = new Bundle(); + data.putString(MESSAGE_DATA_PASSPHRASE, passphrase); + sendMessageToHandler(MESSAGE_OKAY, data); + return; + } + + WrappedSecretKey unlockedSecretKey = null; + + for(WrappedSecretKey clickSecretKey : secretRing.iterator()) { + try { + boolean unlocked = clickSecretKey.unlock(passphrase); + if (unlocked) { + unlockedSecretKey = clickSecretKey; + break; } + } catch (PgpGeneralException e) { + Toast.makeText(activity, R.string.error_could_not_extract_private_key, + Toast.LENGTH_SHORT).show(); + + sendMessageToHandler(MESSAGE_CANCEL); + return; // ran out of keys to try } - keyId = secretKey.getKeyID(); - } else { - keyId = Constants.key.symmetric; } + // Means we got an exception every time + if (unlockedSecretKey == null) { + Toast.makeText(activity, R.string.wrong_passphrase, + Toast.LENGTH_SHORT).show(); + + sendMessageToHandler(MESSAGE_CANCEL); + return; + } + + long masterKeyId = secretRing.getMasterKeyId(); + // cache the new passphrase Log.d(Constants.TAG, "Everything okay! Caching entered passphrase"); - PassphraseCacheService.addCachedPassphrase(activity, keyId, passphrase); - if (!keyOK && clickSecretKey.getKeyID() != keyId) { - PassphraseCacheService.addCachedPassphrase(activity, clickSecretKey.getKeyID(), - passphrase); + PassphraseCacheService.addCachedPassphrase(activity, masterKeyId, passphrase); + if (unlockedSecretKey.getKeyId() != masterKeyId) { + PassphraseCacheService.addCachedPassphrase( + activity, unlockedSecretKey.getKeyId(), passphrase); } // also return passphrase back to activity Bundle data = new Bundle(); data.putString(MESSAGE_DATA_PASSPHRASE, passphrase); - sendMessageToHandler(MESSAGE_OKAY, data); } }); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java index 1628c9e95..40fe7665c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java @@ -38,22 +38,18 @@ import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; -import org.spongycastle.bcpg.sig.KeyFlags; -import org.spongycastle.openpgp.PGPPublicKey; -import org.spongycastle.openpgp.PGPSecretKey; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.util.Choice; +import org.sufficientlysecure.keychain.pgp.UncachedSecretKey; import java.text.DateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; -import java.util.Vector; public class KeyEditor extends LinearLayout implements Editor, OnClickListener { - private PGPSecretKey mKey; + private UncachedSecretKey mKey; private EditorListener mEditorListener = null; @@ -208,7 +204,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { } } - public void setValue(PGPSecretKey key, boolean isMasterKey, int usage, boolean isNewKey) { + public void setValue(UncachedSecretKey key, boolean isMasterKey, int usage, boolean isNewKey) { mKey = key; mIsMasterKey = isMasterKey; @@ -216,13 +212,12 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mDeleteButton.setVisibility(View.INVISIBLE); } - mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(getContext(), key)); - String keyIdStr = PgpKeyHelper.convertKeyIdToHex(key.getKeyID()); + mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(getContext(), key.getAlgorithm())); + String keyIdStr = PgpKeyHelper.convertKeyIdToHex(key.getKeyId()); mKeyId.setText(keyIdStr); - Vector<Choice> choices = new Vector<Choice>(); - boolean isElGamalKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT); - boolean isDSAKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.DSA); + boolean isElGamalKey = (key.isElGamalEncrypt()); + boolean isDSAKey = (key.isDSA()); if (isElGamalKey) { mChkSign.setVisibility(View.INVISIBLE); TableLayout table = (TableLayout) findViewById(R.id.table_keylayout); @@ -248,38 +243,45 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { mIsNewKey = isNewKey; if (isNewKey) { mUsage = usage; - mChkCertify.setChecked((usage & KeyFlags.CERTIFY_OTHER) == KeyFlags.CERTIFY_OTHER); - mChkSign.setChecked((usage & KeyFlags.SIGN_DATA) == KeyFlags.SIGN_DATA); - mChkEncrypt.setChecked(((usage & KeyFlags.ENCRYPT_COMMS) == KeyFlags.ENCRYPT_COMMS) || - ((usage & KeyFlags.ENCRYPT_STORAGE) == KeyFlags.ENCRYPT_STORAGE)); - mChkAuthenticate.setChecked((usage & KeyFlags.AUTHENTICATION) == KeyFlags.AUTHENTICATION); + mChkCertify.setChecked( + (usage & UncachedSecretKey.CERTIFY_OTHER) == UncachedSecretKey.CERTIFY_OTHER); + mChkSign.setChecked( + (usage & UncachedSecretKey.SIGN_DATA) == UncachedSecretKey.SIGN_DATA); + mChkEncrypt.setChecked( + ((usage & UncachedSecretKey.ENCRYPT_COMMS) == UncachedSecretKey.ENCRYPT_COMMS) || + ((usage & UncachedSecretKey.ENCRYPT_STORAGE) == UncachedSecretKey.ENCRYPT_STORAGE)); + mChkAuthenticate.setChecked( + (usage & UncachedSecretKey.AUTHENTICATION) == UncachedSecretKey.AUTHENTICATION); } else { - mUsage = PgpKeyHelper.getKeyUsage(key); + mUsage = key.getKeyUsage(); mOriginalUsage = mUsage; if (key.isMasterKey()) { - mChkCertify.setChecked(PgpKeyHelper.isCertificationKey(key)); + mChkCertify.setChecked(key.canCertify()); } - mChkSign.setChecked(PgpKeyHelper.isSigningKey(key)); - mChkEncrypt.setChecked(PgpKeyHelper.isEncryptionKey(key)); - mChkAuthenticate.setChecked(PgpKeyHelper.isAuthenticationKey(key)); + mChkSign.setChecked(key.canSign()); + mChkEncrypt.setChecked(key.canEncrypt()); + mChkAuthenticate.setChecked(key.canAuthenticate()); } - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - cal.setTime(PgpKeyHelper.getCreationDate(key)); - setCreatedDate(cal); - cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - Date expiryDate = PgpKeyHelper.getExpiryDate(key); + { + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTime(key.getCreationTime()); + setCreatedDate(cal); + } + + Date expiryDate = key.getExpiryTime(); if (expiryDate == null) { setExpiryDate(null); } else { - cal.setTime(PgpKeyHelper.getExpiryDate(key)); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTime(expiryDate); setExpiryDate(cal); mOriginalExpiryDate = cal; } } - public PGPSecretKey getValue() { + public UncachedSecretKey getValue() { return mKey; } @@ -320,16 +322,16 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener { } public int getUsage() { - mUsage = (mUsage & ~KeyFlags.CERTIFY_OTHER) | - (mChkCertify.isChecked() ? KeyFlags.CERTIFY_OTHER : 0); - mUsage = (mUsage & ~KeyFlags.SIGN_DATA) | - (mChkSign.isChecked() ? KeyFlags.SIGN_DATA : 0); - mUsage = (mUsage & ~KeyFlags.ENCRYPT_COMMS) | - (mChkEncrypt.isChecked() ? KeyFlags.ENCRYPT_COMMS : 0); - mUsage = (mUsage & ~KeyFlags.ENCRYPT_STORAGE) | - (mChkEncrypt.isChecked() ? KeyFlags.ENCRYPT_STORAGE : 0); - mUsage = (mUsage & ~KeyFlags.AUTHENTICATION) | - (mChkAuthenticate.isChecked() ? KeyFlags.AUTHENTICATION : 0); + mUsage = (mUsage & ~UncachedSecretKey.CERTIFY_OTHER) | + (mChkCertify.isChecked() ? UncachedSecretKey.CERTIFY_OTHER : 0); + mUsage = (mUsage & ~UncachedSecretKey.SIGN_DATA) | + (mChkSign.isChecked() ? UncachedSecretKey.SIGN_DATA : 0); + mUsage = (mUsage & ~UncachedSecretKey.ENCRYPT_COMMS) | + (mChkEncrypt.isChecked() ? UncachedSecretKey.ENCRYPT_COMMS : 0); + mUsage = (mUsage & ~UncachedSecretKey.ENCRYPT_STORAGE) | + (mChkEncrypt.isChecked() ? UncachedSecretKey.ENCRYPT_STORAGE : 0); + mUsage = (mUsage & ~UncachedSecretKey.AUTHENTICATION) | + (mChkAuthenticate.isChecked() ? UncachedSecretKey.AUTHENTICATION : 0); return mUsage; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index a7719012a..3e8e18ce5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -35,10 +35,9 @@ import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; -import org.spongycastle.openpgp.PGPKeyFlags; -import org.spongycastle.openpgp.PGPSecretKey; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; +import org.sufficientlysecure.keychain.pgp.UncachedSecretKey; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.PassphraseCacheService; @@ -63,7 +62,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor private int mNewKeySize; private boolean mOldItemDeleted = false; private ArrayList<String> mDeletedIDs = new ArrayList<String>(); - private ArrayList<PGPSecretKey> mDeletedKeys = new ArrayList<PGPSecretKey>(); + private ArrayList<UncachedSecretKey> mDeletedKeys = new ArrayList<UncachedSecretKey>(); private boolean mCanBeEdited = true; private ActionBarActivity mActivity; @@ -227,7 +226,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor return mDeletedIDs; } - public ArrayList<PGPSecretKey> getDeletedKeys() { + public ArrayList<UncachedSecretKey> getDeletedKeys() { return mDeletedKeys; } @@ -325,7 +324,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor this.updateEditorsVisible(); } - public void setKeys(Vector<PGPSecretKey> list, Vector<Integer> usages, boolean newKeys) { + public void setKeys(Vector<UncachedSecretKey> list, Vector<Integer> usages, boolean newKeys) { if (mType != TYPE_KEY) { return; } @@ -358,9 +357,9 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor String passphrase; if (mEditors.getChildCount() > 0) { - PGPSecretKey masterKey = ((KeyEditor) mEditors.getChildAt(0)).getValue(); + UncachedSecretKey masterKey = ((KeyEditor) mEditors.getChildAt(0)).getValue(); passphrase = PassphraseCacheService - .getCachedPassphrase(mActivity, masterKey.getKeyID()); + .getCachedPassphrase(mActivity, masterKey.getKeyId()); isMasterKey = false; } else { passphrase = ""; @@ -395,7 +394,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { // get new key from data bundle returned from service Bundle data = message.getData(); - PGPSecretKey newKey = (PGPSecretKey) PgpConversionHelper + UncachedSecretKey newKey = PgpConversionHelper .BytesToPGPSecretKey(data .getByteArray(KeychainIntentService.RESULT_NEW_KEY)); addGeneratedKeyToView(newKey); @@ -413,14 +412,14 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor mActivity.startService(intent); } - private void addGeneratedKeyToView(PGPSecretKey newKey) { + private void addGeneratedKeyToView(UncachedSecretKey newKey) { // add view with new key KeyEditor view = (KeyEditor) mInflater.inflate(R.layout.edit_key_key_item, mEditors, false); view.setEditorListener(SectionView.this); int usage = 0; if (mEditors.getChildCount() == 0) { - usage = PGPKeyFlags.CAN_CERTIFY; + usage = UncachedSecretKey.CERTIFY_OTHER; } view.setValue(newKey, newKey.isMasterKey(), usage, true); mEditors.addView(view); |