diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-10-03 02:20:38 +0200 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-10-03 02:20:38 +0200 |
commit | ef7eab2c8bf7eda281849d66f201070f5e142304 (patch) | |
tree | bf21540073f932b9e6d5c083af7569ddb58f1d5c /OpenKeychain/src/main | |
parent | b9dc21969faa7c4cd7b10638a629690d0df20cf4 (diff) | |
parent | 4b4e885e55f788bd2cf05f3c83f5a4bccb6cd0c0 (diff) | |
download | open-keychain-ef7eab2c8bf7eda281849d66f201070f5e142304.tar.gz open-keychain-ef7eab2c8bf7eda281849d66f201070f5e142304.tar.bz2 open-keychain-ef7eab2c8bf7eda281849d66f201070f5e142304.zip |
Merge branch 'master' of github.com:open-keychain/open-keychain
Conflicts:
OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
Diffstat (limited to 'OpenKeychain/src/main')
15 files changed, 80 insertions, 122 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java index 554899843..f43cbbeef 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java @@ -78,7 +78,7 @@ public abstract class CanonicalizedKeyRing extends KeyRing { public long getEncryptId() throws PgpGeneralException { for(CanonicalizedPublicKey key : publicKeyIterator()) { - if(key.canEncrypt()) { + if (key.canEncrypt() && key.isValid()) { return key.getKeyId(); } } @@ -94,24 +94,6 @@ public abstract class CanonicalizedKeyRing extends KeyRing { } } - public long getSignId() throws PgpGeneralException { - for(CanonicalizedPublicKey key : publicKeyIterator()) { - if(key.canSign()) { - return key.getKeyId(); - } - } - throw new PgpGeneralException("No valid signing key found!"); - } - - public boolean hasSign() throws PgpGeneralException { - try { - getSignId(); - return true; - } catch (PgpGeneralException e) { - return false; - } - } - public void encode(OutputStream stream) throws IOException { getRing().encode(stream); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java index 8fb3402b2..3539a4ceb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java @@ -104,4 +104,10 @@ public class CanonicalizedPublicKey extends UncachedPublicKey { public Integer getKeyUsage() { return super.getKeyUsage(); } + + /** Returns whether this key is valid, ie not expired or revoked. */ + public boolean isValid() { + return !isRevoked() && !isExpired(); + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java index 48a2aaeb6..e20155cc6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java @@ -30,6 +30,8 @@ import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; @@ -74,43 +76,18 @@ public class CanonicalizedSecretKeyRing extends CanonicalizedKeyRing { return new CanonicalizedSecretKey(this, mRing.getSecretKey(id)); } - /** Getter that returns the subkey that should be used for signing. */ - CanonicalizedSecretKey getSigningSubKey() throws PgpGeneralException { - PGPSecretKey key = mRing.getSecretKey(getSignId()); - if(key != null) { - CanonicalizedSecretKey cKey = new CanonicalizedSecretKey(this, key); - if(!cKey.canSign()) { - throw new PgpGeneralException("key error"); + /** Returns the key id which should be used for signing. + * + * This method returns keys which are actually available (ie. secret available, and not stripped, + * revoked, or expired), hence only works on keyrings where a secret key is available! + */ + public long getSecretSignId() throws PgpGeneralException { + for(CanonicalizedSecretKey key : secretKeyIterator()) { + if (key.canSign() && key.isValid() && key.getSecretKeyType().isUsable()) { + return key.getKeyId(); } - return cKey; - } - // TODO handle with proper exception - throw new PgpGeneralException("no signing key available"); - } - - public boolean hasPassphrase() { - PGPSecretKey secretKey = null; - boolean foundValidKey = false; - for (Iterator keys = mRing.getSecretKeys(); keys.hasNext(); ) { - secretKey = (PGPSecretKey) keys.next(); - if (!secretKey.isPrivateKeyEmpty()) { - foundValidKey = true; - break; - } - } - if(!foundValidKey) { - return false; - } - - 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; } + throw new PgpGeneralException("no valid signing key available"); } public IterableIterator<CanonicalizedSecretKey> secretKeyIterator() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java index 3ef4b336e..b682378e9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java @@ -56,10 +56,6 @@ public abstract class KeyRing { abstract public boolean hasEncrypt() throws PgpGeneralException; - abstract public long getSignId() throws PgpGeneralException; - - abstract public boolean hasSign() throws PgpGeneralException; - abstract public int getVerified() throws PgpGeneralException; private static final Pattern USER_ID_PATTERN = Pattern.compile("^(.*?)(?: \\((.*)\\))?(?: <(.*)>)?$"); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java index bb9c7d51c..c4cacaca7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java @@ -51,12 +51,9 @@ public class UncachedPublicKey { /** The revocation signature is NOT checked here, so this may be false! */ public boolean isRevoked() { - for (PGPSignature sig : new IterableIterator<PGPSignature>( - mPublicKey.getSignaturesOfType(isMasterKey() ? PGPSignature.KEY_REVOCATION - : PGPSignature.SUBKEY_REVOCATION))) { - return true; - } - return false; + return mPublicKey.getSignaturesOfType(isMasterKey() + ? PGPSignature.KEY_REVOCATION + : PGPSignature.SUBKEY_REVOCATION).hasNext(); } public Date getCreationTime() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/CachedPublicKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/CachedPublicKeyRing.java index cfb4a915e..ad3ebae5f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/CachedPublicKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/CachedPublicKeyRing.java @@ -136,64 +136,32 @@ public class CachedPublicKeyRing extends KeyRing { @Override public long getEncryptId() throws PgpGeneralException { try { - Cursor subkeys = getSubkeys(); - if (subkeys != null) { - try { - while (subkeys.moveToNext()) { - if (subkeys.getInt(subkeys.getColumnIndexOrThrow(KeychainContract.Keys.CAN_ENCRYPT)) != 0) { - return subkeys.getLong(subkeys.getColumnIndexOrThrow(KeychainContract.Keys.KEY_ID)); - } - } - } finally { - subkeys.close(); - } - } - } catch(Exception e) { - throw new PgpGeneralException(e); - } - throw new PgpGeneralException("No encrypt key found"); - } - - @Override - public boolean hasEncrypt() throws PgpGeneralException { - try { Object data = mProviderHelper.getGenericData(mUri, - KeychainContract.KeyRings.HAS_ENCRYPT, + KeyRings.HAS_ENCRYPT, ProviderHelper.FIELD_TYPE_INTEGER); - return (Long) data > 0; + return (Long) data; } catch(ProviderHelper.NotFoundException e) { throw new PgpGeneralException(e); } } @Override - public long getSignId() throws PgpGeneralException { - try { - Cursor subkeys = getSubkeys(); - if (subkeys != null) { - try { - while (subkeys.moveToNext()) { - if (subkeys.getInt(subkeys.getColumnIndexOrThrow(KeychainContract.Keys.CAN_SIGN)) != 0) { - return subkeys.getLong(subkeys.getColumnIndexOrThrow(KeychainContract.Keys.KEY_ID)); - } - } - } finally { - subkeys.close(); - } - } - } catch(Exception e) { - throw new PgpGeneralException(e); - } - throw new PgpGeneralException("No sign key found"); + public boolean hasEncrypt() throws PgpGeneralException { + return getEncryptId() != 0; } - @Override - public boolean hasSign() throws PgpGeneralException { + /** Returns the key id which should be used for signing. + * + * This method returns keys which are actually available (ie. secret available, and not stripped, + * revoked, or expired), hence only works on keyrings where a secret key is available! + * + */ + public long getSecretSignId() throws PgpGeneralException { try { Object data = mProviderHelper.getGenericData(mUri, - KeychainContract.KeyRings.HAS_SIGN, + KeyRings.HAS_SIGN, ProviderHelper.FIELD_TYPE_INTEGER); - return (Long) data > 0; + return (Long) data; } catch(ProviderHelper.NotFoundException e) { throw new PgpGeneralException(e); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index b7ee453d5..ed1f19dbd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -293,7 +293,7 @@ public class OpenPgpService extends RemoteService { // Find the appropriate subkey to sign with CachedPublicKeyRing signingRing = new ProviderHelper(this).getCachedPublicKeyRing(accSettings.getKeyId()); - final long sigSubKeyId = signingRing.getSignId(); + final long sigSubKeyId = signingRing.getSecretSignId(); // sign-only PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder( @@ -405,7 +405,7 @@ public class OpenPgpService extends RemoteService { // Find the appropriate subkey to sign with CachedPublicKeyRing signingRing = new ProviderHelper(this).getCachedPublicKeyRing(accSettings.getKeyId()); - final long sigSubKeyId = signingRing.getSignId(); + final long sigSubKeyId = signingRing.getSecretSignId(); String passphrase; if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index bb966fec8..0ee3c7093 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -294,7 +294,7 @@ public class KeychainIntentService extends IntentService implements Progressable // Find the appropriate subkey to sign with CachedPublicKeyRing signingRing = new ProviderHelper(this).getCachedPublicKeyRing(sigMasterKeyId); - long sigSubKeyId = signingRing.getSignId(); + long sigSubKeyId = signingRing.getSecretSignId(); // Set signature settings builder.setSignatureMasterKeyId(sigMasterKeyId) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java index 12887eca5..6079062a7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java @@ -166,6 +166,9 @@ public class CreateKeyInputFragment extends Fragment { } private void hideKeyboard() { + if (getActivity() == null) { + return; + } InputMethodManager inputManager = (InputMethodManager) getActivity() .getSystemService(Context.INPUT_METHOD_SERVICE); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 5e23a24ae..6001687a1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -76,9 +76,15 @@ public class DecryptActivity extends DrawerActivity { if (Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) { // get text from clipboard - final CharSequence clipboardText = ClipboardReflection.getClipboardText(DecryptActivity.this); + final CharSequence clipboardText = + ClipboardReflection.getClipboardText(DecryptActivity.this); - AsyncTask<String, Void, Boolean> tadaTask = new AsyncTask<String, Void, Boolean>() { + // if it's null, nothing to do here /o/ + if (clipboardText == null) { + return; + } + + new AsyncTask<String, Void, Boolean>() { @Override protected Boolean doInBackground(String... clipboardText) { @@ -103,11 +109,7 @@ public class DecryptActivity extends DrawerActivity { SubtleAttentionSeeker.tada(findViewById(R.id.clipboard_icon), 1.5f).start(); } } - }; - - if (clipboardText != null) { - tadaTask.execute(clipboardText.toString()); - } + }.execute(clipboardText.toString()); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java index 2b5a9793c..3ea107c48 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java @@ -159,6 +159,9 @@ public class ImportKeysCloudFragment extends Fragment { } private void hideKeyboard() { + if (getActivity() == null) { + return; + } InputMethodManager inputManager = (InputMethodManager) getActivity() .getSystemService(Context.INPUT_METHOD_SERVICE); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java index decd1757f..4bfca9e1d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java @@ -157,8 +157,8 @@ public class PassphraseDialogActivity extends FragmentActivity { /* Get key type for message */ // find a master key id for our key - long masterKeyId = new ProviderHelper(getActivity()).getMasterKeyId(mSubKeyId); - CachedPublicKeyRing keyRing = new ProviderHelper(getActivity()).getCachedPublicKeyRing(masterKeyId); + long masterKeyId = new ProviderHelper(activity).getMasterKeyId(mSubKeyId); + CachedPublicKeyRing keyRing = new ProviderHelper(activity).getCachedPublicKeyRing(masterKeyId); // get the type of key (from the database) CanonicalizedSecretKey.SecretKeyType keyType = keyRing.getSecretKeyType(mSubKeyId); switch (keyType) { @@ -324,6 +324,11 @@ public class PassphraseDialogActivity extends FragmentActivity { } private void finishCaching(String passphrase) { + // any indication this isn't needed anymore, don't do it. + if (mIsCancelled || getActivity() == null) { + return; + } + if (mServiceIntent != null) { // TODO: Not routing passphrase through OpenPGP API currently // due to security concerns... @@ -352,6 +357,10 @@ public class PassphraseDialogActivity extends FragmentActivity { public void onDismiss(DialogInterface dialog) { super.onDismiss(dialog); + if (getActivity() == null) { + return; + } + hideKeyboard(); getActivity().setResult(RESULT_CANCELED); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java index 27339a02f..3eef04aa7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java @@ -206,6 +206,9 @@ public class AddUserIdDialogFragment extends DialogFragment implements OnEditorA } private void hideKeyboard() { + if (getActivity() == null) { + return; + } InputMethodManager inputManager = (InputMethodManager) getActivity() .getSystemService(Context.INPUT_METHOD_SERVICE); 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 a89d4be1c..43f869f02 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 @@ -209,6 +209,10 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor mPassphraseEditText.post(new Runnable() { @Override public void run() { + // The activity might already be gone! Nvm in that case. + if (getActivity() == null) { + return; + } InputMethodManager imm = (InputMethodManager) getActivity() .getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(mPassphraseEditText, InputMethodManager.SHOW_IMPLICIT); @@ -342,13 +346,18 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor } private void hideKeyboard() { + // The activity which called the dialog might no longer exist. Nvm in that case... + if (getActivity() == null) { + return; + } InputMethodManager inputManager = (InputMethodManager) getActivity() .getSystemService(Context.INPUT_METHOD_SERVICE); //check if no view has focus: View v = getActivity().getCurrentFocus(); - if (v == null) + if (v == null) { return; + } inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java index 5e2bec0e9..a05719072 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java @@ -200,6 +200,9 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi } private void hideKeyboard() { + if (getActivity() == null) { + return; + } InputMethodManager inputManager = (InputMethodManager) getActivity() .getSystemService(Context.INPUT_METHOD_SERVICE); |