diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java index 61627ffd8..e1bd415be 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java @@ -735,13 +735,14 @@ public class PgpMain { */ public static void encryptAndSign(Context context, ProgressDialogUpdater progress, InputData data, OutputStream outStream, boolean useAsciiArmor, int compression, - long encryptionKeyIds[], String encryptionPassphrase, int symmetricEncryptionAlgorithm, - long signatureKeyId, int signatureHashAlgorithm, boolean signatureForceV3, - String signaturePassphrase) throws IOException, PgpGeneralException, PGPException, - NoSuchProviderException, NoSuchAlgorithmException, SignatureException { + ArrayList encryptionKeyIds, String encryptionPassphrase, + int symmetricEncryptionAlgorithm, long signatureKeyId, int signatureHashAlgorithm, + boolean signatureForceV3, String signaturePassphrase) throws IOException, + PgpGeneralException, PGPException, NoSuchProviderException, NoSuchAlgorithmException, + SignatureException { if (encryptionKeyIds == null) { - encryptionKeyIds = new long[0]; + encryptionKeyIds = new ArrayList(); } ArmoredOutputStream armorOut = null; @@ -758,7 +759,7 @@ public class PgpMain { PGPSecretKeyRing signingKeyRing = null; PGPPrivateKey signaturePrivateKey = null; - if (encryptionKeyIds.length == 0 && encryptionPassphrase == null) { + if (encryptionKeyIds.size() == 0 && encryptionPassphrase == null) { throw new PgpGeneralException( context.getString(R.string.error_noEncryptionKeysOrPassPhrase)); } @@ -794,7 +795,7 @@ public class PgpMain { PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); - if (encryptionKeyIds.length == 0) { + if (encryptionKeyIds.size() == 0) { // Symmetric encryption Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption"); @@ -803,8 +804,8 @@ public class PgpMain { cPk.addMethod(symmetricEncryptionGenerator); } else { // Asymmetric encryption - for (int i = 0; i < encryptionKeyIds.length; ++i) { - PGPPublicKey key = PgpHelper.getEncryptPublicKey(context, encryptionKeyIds[i]); + for (long id : encryptionKeyIds) { + PGPPublicKey key = PgpHelper.getEncryptPublicKey(context, id); if (key != null) { JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = new JcePublicKeyKeyEncryptionMethodGenerator( diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/CryptoService.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/CryptoService.java index 3d5fc6b77..a86e6a1d6 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/CryptoService.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/CryptoService.java @@ -22,6 +22,7 @@ import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.prefs.Preferences; @@ -46,6 +47,7 @@ import org.openintents.crypto.ICryptoService; import android.app.Service; import android.content.Context; import android.content.Intent; +import android.database.Cursor; import android.net.Uri; import android.os.Binder; import android.os.Bundle; @@ -108,7 +110,7 @@ public class CryptoService extends Service { } private synchronized void encryptSafe(byte[] inputBytes, String[] encryptionUserIds, - AppSettings appSettings, ICryptoCallback callback) throws RemoteException { + ICryptoCallback callback, AppSettings appSettings) throws RemoteException { try { // build InputData and write into OutputStream InputStream inputStream = new ByteArrayInputStream(inputBytes); @@ -117,18 +119,34 @@ public class CryptoService extends Service { OutputStream outputStream = new ByteArrayOutputStream(); - String passphrase = getCachedPassphrase(appSettings.getKeyId()); + // find key ids to given emails in database + boolean manySameUserIds = false; + boolean missingUserIds = false; + ArrayList keyIds = new ArrayList(); + for (String email : encryptionUserIds) { + Uri uri = KeychainContract.KeyRings.buildPublicKeyRingsByEmailsUri(email); + Cursor cur = getContentResolver().query(uri, null, null, null, null); + if (cur.moveToFirst()) { + long id = cur.getLong(cur + .getColumnIndex(KeychainContract.KeyRings.MASTER_KEY_ID)); + keyIds.add(id); + } else { + missingUserIds = true; + Log.d(Constants.TAG, "user id missing"); + } + if (cur.moveToNext()) { + manySameUserIds = true; + Log.d(Constants.TAG, "more than one user id with the same email"); + } + } + + // also encrypt to our self (so that we can decrypt it later!) + keyIds.add(appSettings.getKeyId()); PgpMain.encryptAndSign(mContext, null, inputData, outputStream, - appSettings.isAsciiArmor(), appSettings.getCompression(), new long[] {}, - "test", appSettings.getEncryptionAlgorithm(), Id.key.none, - appSettings.getHashAlgorithm(), true, passphrase); - - // PgpMain.encryptAndSign(this, this, inputData, outputStream, - // appSettings.isAsciiArmor(), - // appSettings.getCompression(), encryptionKeyIds, encryptionPassphrase, - // appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(), - // appSettings.getHashAlgorithm(), true, passphrase); + appSettings.isAsciiArmor(), appSettings.getCompression(), keyIds, null, + appSettings.getEncryptionAlgorithm(), Id.key.none, + appSettings.getHashAlgorithm(), true, null); outputStream.close(); @@ -147,8 +165,22 @@ public class CryptoService extends Service { } } - private synchronized void decryptAndVerifySafe(byte[] inputBytes, ICryptoCallback callback) + private synchronized void encryptAndSignSafe(byte[] inputBytes, String[] encryptionUserIds, + String signatureUserId, ICryptoCallback callback, AppSettings appSettings) throws RemoteException { + + String passphrase = getCachedPassphrase(appSettings.getKeyId()); + + // PgpMain.encryptAndSign(this, this, inputData, outputStream, + // appSettings.isAsciiArmor(), + // appSettings.getCompression(), encryptionKeyIds, encryptionPassphrase, + // appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(), + // appSettings.getHashAlgorithm(), true, passphrase); + + } + + private synchronized void decryptAndVerifySafe(byte[] inputBytes, ICryptoCallback callback, + AppSettings appSettings) throws RemoteException { try { // build InputData and write into OutputStream InputStream inputStream = new ByteArrayInputStream(inputBytes); @@ -226,7 +258,7 @@ public class CryptoService extends Service { @Override public void run() { try { - encryptSafe(inputBytes, encryptionUserIds, settings, callback); + encryptSafe(inputBytes, encryptionUserIds, callback, settings); } catch (RemoteException e) { Log.e(Constants.TAG, "CryptoService", e); } @@ -237,9 +269,26 @@ public class CryptoService extends Service { } @Override - public void encryptAndSign(byte[] inputBytes, String[] encryptionUserIds, - String signatureUserId, ICryptoCallback callback) throws RemoteException { - // TODO Auto-generated method stub + public void encryptAndSign(final byte[] inputBytes, final String[] encryptionUserIds, + final String signatureUserId, final ICryptoCallback callback) + throws RemoteException { + + final AppSettings settings = getAppSettings(); + + Runnable r = new Runnable() { + + @Override + public void run() { + try { + encryptAndSignSafe(inputBytes, encryptionUserIds, signatureUserId, + callback, settings); + } catch (RemoteException e) { + Log.e(Constants.TAG, "CryptoService", e); + } + } + }; + + checkAndEnqueue(r); } @@ -254,12 +303,14 @@ public class CryptoService extends Service { public void decryptAndVerify(final byte[] inputBytes, final ICryptoCallback callback) throws RemoteException { + final AppSettings settings = getAppSettings(); + Runnable r = new Runnable() { @Override public void run() { try { - decryptAndVerifySafe(inputBytes, callback); + decryptAndVerifySafe(inputBytes, callback, settings); } catch (RemoteException e) { Log.e(Constants.TAG, "CryptoService", e); } diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainApiService.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainApiService.java index 41250f645..d7457f132 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainApiService.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainApiService.java @@ -103,12 +103,12 @@ public class KeychainApiService extends Service { InputData input = new InputData(inputStream, inputLength); OutputStream output = new ByteArrayOutputStream(); - - PgpMain.encryptAndSign(mContext, null, input, output, useAsciiArmor, compression, - encryptionKeyIds, encryptionPassphrase, symmetricEncryptionAlgorithm, - signatureKeyId, signatureHashAlgorithm, signatureForceV3, signaturePassphrase); - - output.close(); +// +// PgpMain.encryptAndSign(mContext, null, input, output, useAsciiArmor, compression, +// encryptionKeyIds, encryptionPassphrase, symmetricEncryptionAlgorithm, +// signatureKeyId, signatureHashAlgorithm, signatureForceV3, signaturePassphrase); +// +// output.close(); // if (isBlob) { // ContentResolver cr = getContentResolver(); diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainIntentService.java index d1ea9281d..1ffb390c0 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -27,6 +27,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.spongycastle.openpgp.PGPSecretKey; @@ -75,9 +77,11 @@ public class KeychainIntentService extends IntentService implements ProgressDial public static final String ACTION_SAVE_KEYRING = Constants.INTENT_PREFIX + "SAVE_KEYRING"; public static final String ACTION_GENERATE_KEY = Constants.INTENT_PREFIX + "GENERATE_KEY"; - public static final String ACTION_GENERATE_DEFAULT_RSA_KEYS = Constants.INTENT_PREFIX + "GENERATE_DEFAULT_RSA_KEYS"; + public static final String ACTION_GENERATE_DEFAULT_RSA_KEYS = Constants.INTENT_PREFIX + + "GENERATE_DEFAULT_RSA_KEYS"; - public static final String ACTION_DELETE_FILE_SECURELY = Constants.INTENT_PREFIX + "DELETE_FILE_SECURELY"; + public static final String ACTION_DELETE_FILE_SECURELY = Constants.INTENT_PREFIX + + "DELETE_FILE_SECURELY"; public static final String ACTION_IMPORT_KEYRING = Constants.INTENT_PREFIX + "IMPORT_KEYRING"; public static final String ACTION_EXPORT_KEYRING = Constants.INTENT_PREFIX + "EXPORT_KEYRING"; @@ -216,8 +220,8 @@ public class KeychainIntentService extends IntentService implements ProgressDial return; } - if (!(extras.containsKey(EXTRA_MESSENGER) || extras.containsKey(EXTRA_DATA) || - (intent.getAction() == null))) { + if (!(extras.containsKey(EXTRA_MESSENGER) || extras.containsKey(EXTRA_DATA) || (intent + .getAction() == null))) { Log.e(Constants.TAG, "Extra bundle must contain a messenger, a data bundle, and an action!"); return; @@ -229,9 +233,9 @@ public class KeychainIntentService extends IntentService implements ProgressDial OtherHelper.logDebugBundle(data, "EXTRA_DATA"); String action = intent.getAction(); - + // execute action from extra bundle - if( ACTION_ENCRYPT_SIGN.equals(action)) { + if (ACTION_ENCRYPT_SIGN.equals(action)) { try { /* Input */ int target = data.getInt(TARGET); @@ -312,6 +316,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial } /* Operation */ + // convert to arraylist + ArrayList keyIdsList = new ArrayList(encryptionKeyIds.length); + for (long n : encryptionKeyIds) + keyIdsList.add(n); if (generateSignature) { Log.d(Constants.TAG, "generating signature..."); @@ -329,7 +337,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial } else { Log.d(Constants.TAG, "encrypt..."); PgpMain.encryptAndSign(this, this, inputData, outStream, useAsciiArmor, - compressionId, encryptionKeyIds, encryptionPassphrase, Preferences + compressionId, keyIdsList, encryptionPassphrase, Preferences .getPreferences(this).getDefaultEncryptionAlgorithm(), secretKeyId, Preferences.getPreferences(this).getDefaultHashAlgorithm(), Preferences @@ -380,8 +388,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial } catch (Exception e) { sendErrorToHandler(e); } - } - else if(ACTION_DECRYPT_VERIFY.equals(action)) { + } else if (ACTION_DECRYPT_VERIFY.equals(action)) { try { /* Input */ int target = data.getInt(TARGET); @@ -510,8 +517,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial } catch (Exception e) { sendErrorToHandler(e); } - } - else if(ACTION_SAVE_KEYRING.equals(action)) { + } else if (ACTION_SAVE_KEYRING.equals(action)) { try { /* Input */ String oldPassPhrase = data.getString(SAVE_KEYRING_CURRENT_PASSPHRASE); @@ -547,8 +553,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial } catch (Exception e) { sendErrorToHandler(e); } - } - else if(ACTION_GENERATE_KEY.equals(action)) { + } else if (ACTION_GENERATE_KEY.equals(action)) { try { /* Input */ int algorithm = data.getInt(GENERATE_KEY_ALGORITHM); @@ -575,8 +580,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial } catch (Exception e) { sendErrorToHandler(e); } - } - else if(ACTION_GENERATE_DEFAULT_RSA_KEYS.equals(action)) { + } else if (ACTION_GENERATE_DEFAULT_RSA_KEYS.equals(action)) { // generate one RSA 2048 key for signing and one subkey for encrypting! try { /* Input */ @@ -602,8 +606,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial } catch (Exception e) { sendErrorToHandler(e); } - } - else if(ACTION_DELETE_FILE_SECURELY.equals(action)) { + } else if (ACTION_DELETE_FILE_SECURELY.equals(action)) { try { /* Input */ String deleteFile = data.getString(DELETE_FILE); @@ -624,8 +627,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial } catch (Exception e) { sendErrorToHandler(e); } - } - else if(ACTION_IMPORT_KEYRING.equals(action)) { + } else if (ACTION_IMPORT_KEYRING.equals(action)) { try { /* Input */ @@ -672,8 +674,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial } catch (Exception e) { sendErrorToHandler(e); } - } - else if(ACTION_EXPORT_KEYRING.equals(action)) { + } else if (ACTION_EXPORT_KEYRING.equals(action)) { try { /* Input */ @@ -721,8 +722,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial } catch (Exception e) { sendErrorToHandler(e); } - } - else if(ACTION_UPLOAD_KEYRING.equals(action)) { + } else if (ACTION_UPLOAD_KEYRING.equals(action)) { try { /* Input */ @@ -746,8 +746,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial } catch (Exception e) { sendErrorToHandler(e); } - } - else if(ACTION_QUERY_KEYRING.equals(action)) { + } else if (ACTION_QUERY_KEYRING.equals(action)) { try { /* Input */ @@ -775,8 +774,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial } catch (Exception e) { sendErrorToHandler(e); } - } - else if(ACTION_SIGN_KEYRING.equals(action)) { + } else if (ACTION_SIGN_KEYRING.equals(action)) { try { /* Input */ diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/EncryptActivity.java index e38044526..751e6deae 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -39,11 +39,10 @@ import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Choice; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.R; - import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuItem; - +import android.annotation.SuppressLint; import android.app.ProgressDialog; import android.content.Intent; import android.net.Uri; @@ -64,7 +63,6 @@ import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import android.widget.ViewFlipper; - import java.io.File; import java.util.Vector; @@ -437,6 +435,7 @@ public class EncryptActivity extends SherlockFragmentActivity { * @param encryptToClipboardEnabled * @param encryptToClipboardStringRes */ + @SuppressLint("NewApi") private void setActionbarButtons(boolean encryptEnabled, int encryptStringRes, boolean encryptToClipboardEnabled, int encryptToClipboardStringRes) { mEncryptEnabled = encryptEnabled; @@ -779,10 +778,10 @@ public class EncryptActivity extends SherlockFragmentActivity { Intent emailIntent = new Intent(Intent.ACTION_SEND); - //Type is set to text/plain so that encrypted messages can - //be sent with Whatsapp, Hangouts, SMS etc... + // Type is set to text/plain so that encrypted messages can + // be sent with Whatsapp, Hangouts, SMS etc... emailIntent.setType("text/plain"); - + emailIntent.putExtra(Intent.EXTRA_TEXT, output); if (mSubject != null) { emailIntent.putExtra(Intent.EXTRA_SUBJECT, mSubject);