Testing encrypt by service

This commit is contained in:
Dominik Schürmann 2013-09-06 13:48:27 +02:00
parent fabb0389fc
commit 3a66c1c25a
4 changed files with 83 additions and 30 deletions

View File

@ -73,11 +73,18 @@ public class CryptoProviderDemoActivity extends Activity {
final ICryptoCallback.Stub encryptCallback = new ICryptoCallback.Stub() { final ICryptoCallback.Stub encryptCallback = new ICryptoCallback.Stub() {
@Override @Override
public void onSuccess(byte[] outputBytes, CryptoSignatureResult signatureResult) public void onSuccess(final byte[] outputBytes, CryptoSignatureResult signatureResult)
throws RemoteException { throws RemoteException {
Log.d(Constants.TAG, "onEncryptSignSuccess"); Log.d(Constants.TAG, "onEncryptSignSuccess");
// TODO runOnUiThread(new Runnable() {
@Override
public void run() {
mCiphertext.setText(new String(outputBytes));
}
});
} }
@Override @Override
@ -91,11 +98,19 @@ public class CryptoProviderDemoActivity extends Activity {
final ICryptoCallback.Stub decryptCallback = new ICryptoCallback.Stub() { final ICryptoCallback.Stub decryptCallback = new ICryptoCallback.Stub() {
@Override @Override
public void onSuccess(byte[] outputBytes, CryptoSignatureResult signatureResult) public void onSuccess(final byte[] outputBytes, final CryptoSignatureResult signatureResult)
throws RemoteException { throws RemoteException {
Log.d(Constants.TAG, "onDecryptVerifySuccess"); Log.d(Constants.TAG, "onDecryptVerifySuccess");
mMessage.setText(new String(outputBytes)); runOnUiThread(new Runnable() {
@Override
public void run() {
mMessage.setText(new String(outputBytes) + "\n\n" + signatureResult.toString());
}
});
} }
@Override @Override

View File

@ -768,6 +768,9 @@ public class ProviderHelper {
public static AppSettings getApiAppSettings(Context context, Uri uri) { public static AppSettings getApiAppSettings(Context context, Uri uri) {
AppSettings settings = new AppSettings(); AppSettings settings = new AppSettings();
Cursor cur = context.getContentResolver().query(uri, null, null, null, null); Cursor cur = context.getContentResolver().query(uri, null, null, null, null);
if (cur == null) {
return null;
}
if (cur.moveToFirst()) { if (cur.moveToFirst()) {
settings.setPackageName(cur.getString(cur settings.setPackageName(cur.getString(cur
.getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME))); .getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME)));

View File

@ -23,6 +23,7 @@ import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.prefs.Preferences;
import org.openintents.crypto.CryptoError; import org.openintents.crypto.CryptoError;
import org.openintents.crypto.CryptoSignatureResult; import org.openintents.crypto.CryptoSignatureResult;
@ -32,18 +33,19 @@ import org.sufficientlysecure.keychain.helper.PgpMain;
import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.remote_api.IServiceActivityCallback; import org.sufficientlysecure.keychain.remote_api.IServiceActivityCallback;
import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.util.PausableThreadPoolExecutor; import org.sufficientlysecure.keychain.util.PausableThreadPoolExecutor;
import org.openintents.crypto.ICryptoCallback; import org.openintents.crypto.ICryptoCallback;
import org.openintents.crypto.ICryptoService; import org.openintents.crypto.ICryptoService;
import android.app.Service; import android.app.Service;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
@ -89,29 +91,50 @@ public class CryptoService extends Service {
} }
} }
private String getCachedPassphrase(long keyId) {
String passphrase = PassphraseCacheService.getCachedPassphrase(mContext, keyId);
if (passphrase == null) {
Log.d(Constants.TAG, "No passphrase! Activity required!");
// start passphrase dialog
Bundle extras = new Bundle();
extras.putLong(CryptoServiceActivity.EXTRA_SECRET_KEY_ID, keyId);
pauseQueueAndStartServiceActivity(CryptoServiceActivity.ACTION_CACHE_PASSPHRASE, extras);
}
return passphrase;
}
private synchronized void encryptSafe(byte[] inputBytes, String[] encryptionUserIds, private synchronized void encryptSafe(byte[] inputBytes, String[] encryptionUserIds,
ICryptoCallback callback) throws RemoteException { AppSettings appSettings, ICryptoCallback callback) throws RemoteException {
try { try {
// build InputData and write into OutputStream // build InputData and write into OutputStream
InputStream inputStream = new ByteArrayInputStream(inputBytes); InputStream inputStream = new ByteArrayInputStream(inputBytes);
long inputLength = inputBytes.length; long inputLength = inputBytes.length;
InputData inputData = new InputData(inputStream, inputLength); InputData inputData = new InputData(inputStream, inputLength);
OutputStream outStream = new ByteArrayOutputStream(); OutputStream outputStream = new ByteArrayOutputStream();
// TODO: hardcoded... String passphrase = getCachedPassphrase(appSettings.getKeyId());
boolean useAsciiArmor = true;
int compressionId = 2; // zlib
// PgpMain.encryptAndSign(this, this, inputData, outStream, useAsciiArmor, PgpMain.encryptAndSign(mContext, null, inputData, outputStream,
// compressionId, encryptionKeyIds, encryptionPassphrase, Preferences appSettings.isAsciiArmor(), appSettings.getCompression(), new long[] {},
// .getPreferences(this).getDefaultEncryptionAlgorithm(), "test", appSettings.getEncryptionAlgorithm(), Id.key.none,
// secretKeyId, appSettings.getHashAlgorithm(), true, passphrase);
// Preferences.getPreferences(this).getDefaultHashAlgorithm(), Preferences
// .getPreferences(this).getForceV3Signatures(),
// PassphraseCacheService.getCachedPassphrase(this, secretKeyId));
outStream.close(); // PgpMain.encryptAndSign(this, this, inputData, outputStream,
// appSettings.isAsciiArmor(),
// appSettings.getCompression(), encryptionKeyIds, encryptionPassphrase,
// appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(),
// appSettings.getHashAlgorithm(), true, passphrase);
outputStream.close();
byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
// return over handler on client side
callback.onSuccess(outputBytes, null);
} catch (Exception e) { } catch (Exception e) {
Log.e(Constants.TAG, "KeychainService, Exception!", e); Log.e(Constants.TAG, "KeychainService, Exception!", e);
@ -133,6 +156,8 @@ public class CryptoService extends Service {
OutputStream outputStream = new ByteArrayOutputStream(); OutputStream outputStream = new ByteArrayOutputStream();
// TODO: This allows to decrypt messages with ALL secret keys, not only the one for the
// app, Fix this?
long secretKeyId = PgpMain.getDecryptionKeyId(mContext, inputStream); long secretKeyId = PgpMain.getDecryptionKeyId(mContext, inputStream);
if (secretKeyId == Id.key.none) { if (secretKeyId == Id.key.none) {
throw new PgpMain.PgpGeneralException(getString(R.string.error_noSecretKeyFound)); throw new PgpMain.PgpGeneralException(getString(R.string.error_noSecretKeyFound));
@ -142,16 +167,7 @@ public class CryptoService extends Service {
Log.d(Constants.TAG, "secretKeyId " + secretKeyId); Log.d(Constants.TAG, "secretKeyId " + secretKeyId);
String passphrase = PassphraseCacheService.getCachedPassphrase(mContext, secretKeyId); String passphrase = getCachedPassphrase(secretKeyId);
if (passphrase == null) {
Log.d(Constants.TAG, "No passphrase! Activity required!");
// start passphrase dialog
Bundle extras = new Bundle();
extras.putLong(CryptoServiceActivity.EXTRA_SECRET_KEY_ID, secretKeyId);
pauseQueueAndStartServiceActivity(CryptoServiceActivity.ACTION_CACHE_PASSPHRASE, extras);
}
// if (signedOnly) { // if (signedOnly) {
// resultData = PgpMain.verifyText(this, this, inputData, outStream, // resultData = PgpMain.verifyText(this, this, inputData, outStream,
@ -202,12 +218,14 @@ public class CryptoService extends Service {
public void encrypt(final byte[] inputBytes, final String[] encryptionUserIds, public void encrypt(final byte[] inputBytes, final String[] encryptionUserIds,
final ICryptoCallback callback) throws RemoteException { final ICryptoCallback callback) throws RemoteException {
final AppSettings settings = getAppSettings();
Runnable r = new Runnable() { Runnable r = new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
encryptSafe(inputBytes, encryptionUserIds, callback); encryptSafe(inputBytes, encryptionUserIds, settings, callback);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoService", e); Log.e(Constants.TAG, "CryptoService", e);
} }
@ -330,6 +348,23 @@ public class CryptoService extends Service {
return false; return false;
} }
private AppSettings getAppSettings() {
String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid());
// is calling package allowed to use this service?
for (int i = 0; i < callingPackages.length; i++) {
String currentPkg = callingPackages[i];
Uri uri = KeychainContract.ApiApps.buildByPackageNameUri(currentPkg);
AppSettings settings = ProviderHelper.getApiAppSettings(this, uri);
return settings;
}
return null;
}
/** /**
* Checks if packageName is a registered app for the API. * Checks if packageName is a registered app for the API.
* *

View File

@ -178,7 +178,7 @@ public class PassphraseCacheService extends Service {
} }
masterKeyId = masterKey.getKeyID(); masterKeyId = masterKey.getKeyID();
} }
Log.d(TAG, "getCachedPassphraseImpl() for masterKeyId" + masterKeyId); Log.d(TAG, "getCachedPassphraseImpl() for masterKeyId " + masterKeyId);
// get cached passphrase // get cached passphrase
String cachedPassphrase = mPassphraseCache.get(masterKeyId); String cachedPassphrase = mPassphraseCache.get(masterKeyId);