From b77fb2fcc0371248beaf86a1db092e7ad99e6446 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 11 Apr 2014 03:21:39 +0200 Subject: get rid of more getMasterKeyId usage, work on getKeyRingsAsArmoredString --- .../keychain/provider/ProviderHelper.java | 114 +++++++++++---------- .../keychain/service/PassphraseCacheService.java | 17 +-- .../keychain/ui/EditKeyActivity.java | 4 - .../keychain/ui/EncryptAsymmetricFragment.java | 5 +- .../keychain/ui/ViewKeyActivity.java | 24 +++-- .../ui/dialog/ShareQrCodeDialogFragment.java | 23 +++-- 6 files changed, 99 insertions(+), 88 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 3e0520c2a..43fbf7045 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -461,70 +461,49 @@ public class ProviderHelper { return ContentProviderOperation.newInsert(uri).withValues(values).build(); } - public static ArrayList getKeyRingsAsArmoredString(Context context, long[] masterKeyIds) { - ArrayList output = new ArrayList(); - - if (masterKeyIds != null && masterKeyIds.length > 0) { - - Cursor cursor = getCursorWithSelectedKeyringMasterKeyIds(context, masterKeyIds); - - if (cursor != null) { - int masterIdCol = cursor.getColumnIndex(KeyRingData.MASTER_KEY_ID); - int dataCol = cursor.getColumnIndex(KeyRingData.KEY_RING_DATA); - if (cursor.moveToFirst()) { - do { - Log.d(Constants.TAG, "masterKeyId: " + cursor.getLong(masterIdCol)); + private static String getKeyRingAsArmoredString(Context context, byte[] data) throws IOException { + Object keyRing = null; + if (data != null) { + keyRing = PgpConversionHelper.BytesToPGPKeyRing(data); + } - // get actual keyring data blob and write it to ByteArrayOutputStream - try { - Object keyRing = null; - byte[] data = cursor.getBlob(dataCol); - if (data != null) { - keyRing = PgpConversionHelper.BytesToPGPKeyRing(data); - } + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ArmoredOutputStream aos = new ArmoredOutputStream(bos); + aos.setHeader("Version", PgpHelper.getFullVersion(context)); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ArmoredOutputStream aos = new ArmoredOutputStream(bos); - aos.setHeader("Version", PgpHelper.getFullVersion(context)); + if (keyRing instanceof PGPSecretKeyRing) { + aos.write(((PGPSecretKeyRing) keyRing).getEncoded()); + } else if (keyRing instanceof PGPPublicKeyRing) { + aos.write(((PGPPublicKeyRing) keyRing).getEncoded()); + } + aos.close(); - if (keyRing instanceof PGPSecretKeyRing) { - aos.write(((PGPSecretKeyRing) keyRing).getEncoded()); - } else if (keyRing instanceof PGPPublicKeyRing) { - aos.write(((PGPPublicKeyRing) keyRing).getEncoded()); - } - aos.close(); + String armoredKey = bos.toString("UTF-8"); - String armoredKey = bos.toString("UTF-8"); + Log.d(Constants.TAG, "armoredKey:" + armoredKey); - Log.d(Constants.TAG, "armoredKey:" + armoredKey); + return armoredKey; + } - output.add(armoredKey); - } catch (IOException e) { - Log.e(Constants.TAG, "IOException", e); - } - } while (cursor.moveToNext()); - } - } + public static String getKeyRingAsArmoredString(Context context, Uri uri) + throws NotFoundException, IOException { + byte[] data = (byte[]) ProviderHelper.getGenericData( + context, uri, KeyRingData.KEY_RING_DATA, ProviderHelper.FIELD_TYPE_BLOB); + return getKeyRingAsArmoredString(context, data); + } - if (cursor != null) { - cursor.close(); - } + // TODO This method is NOT ACTUALLY USED. Is this preparation for something, or just dead code? + public static ArrayList getKeyRingsAsArmoredString(Context context, long[] masterKeyIds) + throws IOException { + ArrayList output = new ArrayList(); - } else { + if (masterKeyIds == null || masterKeyIds.length == 0) { Log.e(Constants.TAG, "No master keys given!"); - } - - if (output.size() > 0) { return output; - } else { - return null; } - } - - private static Cursor getCursorWithSelectedKeyringMasterKeyIds(Context context, long[] masterKeyIds) { - Cursor cursor = null; - if (masterKeyIds != null && masterKeyIds.length > 0) { + // Build a cursor for the selected masterKeyIds + Cursor cursor = null; { String inMasterKeyList = KeyRingData.MASTER_KEY_ID + " IN ("; for (int i = 0; i < masterKeyIds.length; ++i) { if (i != 0) { @@ -536,10 +515,37 @@ public class ProviderHelper { cursor = context.getContentResolver().query(KeyRingData.buildPublicKeyRingUri(), new String[] { KeyRingData._ID, KeyRingData.MASTER_KEY_ID, KeyRingData.KEY_RING_DATA - }, inMasterKeyList, null, null); + }, inMasterKeyList, null, null); + } + + if (cursor != null) { + int masterIdCol = cursor.getColumnIndex(KeyRingData.MASTER_KEY_ID); + int dataCol = cursor.getColumnIndex(KeyRingData.KEY_RING_DATA); + if (cursor.moveToFirst()) { + do { + Log.d(Constants.TAG, "masterKeyId: " + cursor.getLong(masterIdCol)); + + byte[] data = cursor.getBlob(dataCol); + + // get actual keyring data blob and write it to ByteArrayOutputStream + try { + output.add(getKeyRingAsArmoredString(context, data)); + } catch (IOException e) { + Log.e(Constants.TAG, "IOException", e); + } + } while (cursor.moveToNext()); + } + } + + if (cursor != null) { + cursor.close(); } - return cursor; + if (output.size() > 0) { + return output; + } else { + return null; + } } public static ArrayList getRegisteredApiApps(Context context) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index 66411ce0b..91d9b5584 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -200,7 +200,7 @@ public class PassphraseCacheService extends Service { return cachedPassphrase; } - public static boolean hasPassphrase(PGPSecretKeyRing secretKeyRing) throws PGPException { + public static boolean hasPassphrase(PGPSecretKeyRing secretKeyRing) { PGPSecretKey secretKey = null; boolean foundValidKey = false; for (Iterator keys = secretKeyRing.getSecretKeys(); keys.hasNext(); ) { @@ -214,10 +214,15 @@ public class PassphraseCacheService extends Service { return false; } - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() - .setProvider("SC").build("".toCharArray()); - PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor); - return testKey == null; + try { + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() + .setProvider("SC").build("".toCharArray()); + PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor); + return testKey == null; + } catch(PGPException e) { + // this means the crc check failed -> passphrase required + return true; + } } /** @@ -231,8 +236,6 @@ public class PassphraseCacheService extends Service { try { PGPSecretKeyRing secRing = ProviderHelper.getPGPSecretKeyRing(context, secretKeyId); return hasPassphrase(secRing); - } catch (PGPException e) { - // silently catch } catch (ProviderHelper.NotFoundException e) { Log.e(Constants.TAG, "key not found!", e); } 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 a009410a6..696f79cd7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -326,10 +326,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener Log.e(Constants.TAG, "Keyring not found: " + e.getMessage(), e); Toast.makeText(this, R.string.error_no_secret_key_found, Toast.LENGTH_SHORT).show(); finish(); - } catch (PGPException e) { - Log.e(Constants.TAG, "Error extracting key: " + e.getMessage(), e); - Toast.makeText(this, R.string.error_no_secret_key_found, Toast.LENGTH_LONG).show(); - finish(); } } 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 2ec4dd89e..a99c9eca8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -165,10 +165,11 @@ public class EncryptAsymmetricFragment extends Fragment { if (preselectedEncryptionKeyIds != null) { Vector goodIds = new Vector(); for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) { - // TODO check for available encrypt keys... is this even relevant? + // TODO One query per selected key?! wtf try { long id = ProviderHelper.getMasterKeyId(getActivity(), - KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(preselectedEncryptionKeyIds[i])) + KeyRings.buildUnifiedKeyRingsFindBySubkeyUri( + Long.toString(preselectedEncryptionKeyIds[i])) ); goodIds.add(id); } catch (ProviderHelper.NotFoundException 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 dceb9a0fc..ca26cac1c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -219,12 +219,8 @@ public class ViewKeyActivity extends ActionBarActivity { } else { // get public keyring as ascii armored string try { - long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); - - ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString( - this, new long[]{masterKeyId}); - - content = keyringArmored.get(0); + Uri uri = KeychainContract.KeyRingData.buildPublicKeyRingUri(dataUri); + content = ProviderHelper.getKeyRingAsArmoredString(this, uri); // Android will fail with android.os.TransactionTooLargeException if key is too big // see http://www.lonestarprod.com/?p=34 @@ -233,8 +229,12 @@ public class ViewKeyActivity extends ActionBarActivity { AppMsg.STYLE_ALERT).show(); return; } + } catch (IOException e) { + Log.e(Constants.TAG, "error processing key!", e); + AppMsg.makeText(this, R.string.error_invalid_data, AppMsg.STYLE_ALERT).show(); } catch (ProviderHelper.NotFoundException e) { Log.e(Constants.TAG, "key not found!", e); + AppMsg.makeText(this, R.string.error_key_not_found, AppMsg.STYLE_ALERT).show(); } } @@ -259,16 +259,18 @@ public class ViewKeyActivity extends ActionBarActivity { private void copyToClipboard(Uri dataUri) { // get public keyring as ascii armored string try { - long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); - - ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString( - this, new long[]{masterKeyId}); + Uri uri = KeychainContract.KeyRingData.buildPublicKeyRingUri(dataUri); + String keyringArmored = ProviderHelper.getKeyRingAsArmoredString(this, uri); - ClipboardReflection.copyToClipboard(this, keyringArmored.get(0)); + ClipboardReflection.copyToClipboard(this, keyringArmored); AppMsg.makeText(this, R.string.key_copied_to_clipboard, AppMsg.STYLE_INFO) .show(); + } catch (IOException e) { + Log.e(Constants.TAG, "error processing key!", e); + AppMsg.makeText(this, R.string.error_key_processing, AppMsg.STYLE_ALERT).show(); } catch (ProviderHelper.NotFoundException e) { Log.e(Constants.TAG, "key not found!", e); + AppMsg.makeText(this, R.string.error_key_not_found, AppMsg.STYLE_ALERT).show(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java index d2d21093e..01d3db235 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java @@ -28,14 +28,19 @@ import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; + +import com.devspark.appmsg.AppMsg; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.QrCodeUtils; +import java.io.IOException; import java.util.ArrayList; public class ShareQrCodeDialogFragment extends DialogFragment { @@ -106,20 +111,18 @@ public class ShareQrCodeDialogFragment extends DialogFragment { } else { mText.setText(R.string.share_qr_code_dialog_start); - // TODO works, but - long masterKeyId = 0; try { - masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri); + Uri uri = KeychainContract.KeyRingData.buildPublicKeyRingUri(dataUri); + content = ProviderHelper.getKeyRingAsArmoredString(getActivity(), uri); + } catch (IOException e) { + Log.e(Constants.TAG, "error processing key!", e); + AppMsg.makeText(getActivity(), R.string.error_invalid_data, AppMsg.STYLE_ALERT).show(); + return null; } catch (ProviderHelper.NotFoundException e) { Log.e(Constants.TAG, "key not found!", e); + AppMsg.makeText(getActivity(), R.string.error_key_not_found, AppMsg.STYLE_ALERT).show(); + return null; } - // get public keyring as ascii armored string - ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString( - getActivity(), new long[] { masterKeyId }); - - // TODO: binary? - - content = keyringArmored.get(0); // OnClickListener are set in onResume to prevent automatic dismissing of Dialogs // http://bit.ly/O5vfaR -- cgit v1.2.3