Work on encryption in new service

This commit is contained in:
Dominik Schürmann 2013-09-06 18:36:16 +02:00
parent 9e8ee3353a
commit d6dd81d444
5 changed files with 114 additions and 65 deletions

View File

@ -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<Long> 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<Long>();
}
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(

View File

@ -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<Long> keyIds = new ArrayList<Long>();
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);
}

View File

@ -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();

View File

@ -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;
@ -231,7 +235,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
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<Long> keyIdsList = new ArrayList<Long>(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 */

View File

@ -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,8 +778,8 @@ 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);