From 3a66c1c25aff1dadf4779c2df0fac04f3a9f3c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 6 Sep 2013 13:48:27 +0200 Subject: Testing encrypt by service --- .../keychain/demo/CryptoProviderDemoActivity.java | 23 +++++- .../keychain/provider/ProviderHelper.java | 3 + .../keychain/remote_api/CryptoService.java | 85 +++++++++++++++------- .../keychain/service/PassphraseCacheService.java | 2 +- 4 files changed, 83 insertions(+), 30 deletions(-) diff --git a/OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/CryptoProviderDemoActivity.java b/OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/CryptoProviderDemoActivity.java index 7dcd7c66f..319820d7c 100644 --- a/OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/CryptoProviderDemoActivity.java +++ b/OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/CryptoProviderDemoActivity.java @@ -73,11 +73,18 @@ public class CryptoProviderDemoActivity extends Activity { final ICryptoCallback.Stub encryptCallback = new ICryptoCallback.Stub() { @Override - public void onSuccess(byte[] outputBytes, CryptoSignatureResult signatureResult) + public void onSuccess(final byte[] outputBytes, CryptoSignatureResult signatureResult) throws RemoteException { Log.d(Constants.TAG, "onEncryptSignSuccess"); - // TODO + runOnUiThread(new Runnable() { + + @Override + public void run() { + mCiphertext.setText(new String(outputBytes)); + + } + }); } @Override @@ -91,11 +98,19 @@ public class CryptoProviderDemoActivity extends Activity { final ICryptoCallback.Stub decryptCallback = new ICryptoCallback.Stub() { @Override - public void onSuccess(byte[] outputBytes, CryptoSignatureResult signatureResult) + public void onSuccess(final byte[] outputBytes, final CryptoSignatureResult signatureResult) throws RemoteException { 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 diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 42210db6a..d0fcfe999 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -768,6 +768,9 @@ public class ProviderHelper { public static AppSettings getApiAppSettings(Context context, Uri uri) { AppSettings settings = new AppSettings(); Cursor cur = context.getContentResolver().query(uri, null, null, null, null); + if (cur == null) { + return null; + } if (cur.moveToFirst()) { settings.setPackageName(cur.getString(cur .getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME))); 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 2e6ab4263..125967c66 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/CryptoService.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/remote_api/CryptoService.java @@ -23,6 +23,7 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.prefs.Preferences; import org.openintents.crypto.CryptoError; 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.Log; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote_api.IServiceActivityCallback; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.util.PausableThreadPoolExecutor; - import org.openintents.crypto.ICryptoCallback; import org.openintents.crypto.ICryptoService; import android.app.Service; import android.content.Context; import android.content.Intent; +import android.net.Uri; import android.os.Binder; import android.os.Bundle; 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, - ICryptoCallback callback) throws RemoteException { + AppSettings appSettings, ICryptoCallback callback) throws RemoteException { try { // build InputData and write into OutputStream InputStream inputStream = new ByteArrayInputStream(inputBytes); long inputLength = inputBytes.length; InputData inputData = new InputData(inputStream, inputLength); - OutputStream outStream = new ByteArrayOutputStream(); + OutputStream outputStream = new ByteArrayOutputStream(); + + String passphrase = getCachedPassphrase(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); - // TODO: hardcoded... - boolean useAsciiArmor = true; - int compressionId = 2; // zlib + outputStream.close(); - // PgpMain.encryptAndSign(this, this, inputData, outStream, useAsciiArmor, - // compressionId, encryptionKeyIds, encryptionPassphrase, Preferences - // .getPreferences(this).getDefaultEncryptionAlgorithm(), - // secretKeyId, - // Preferences.getPreferences(this).getDefaultHashAlgorithm(), Preferences - // .getPreferences(this).getForceV3Signatures(), - // PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); + byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray(); - outStream.close(); + // return over handler on client side + callback.onSuccess(outputBytes, null); } catch (Exception e) { Log.e(Constants.TAG, "KeychainService, Exception!", e); @@ -133,6 +156,8 @@ public class CryptoService extends Service { 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); if (secretKeyId == Id.key.none) { throw new PgpMain.PgpGeneralException(getString(R.string.error_noSecretKeyFound)); @@ -142,16 +167,7 @@ public class CryptoService extends Service { Log.d(Constants.TAG, "secretKeyId " + secretKeyId); - String passphrase = PassphraseCacheService.getCachedPassphrase(mContext, 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); - } + String passphrase = getCachedPassphrase(secretKeyId); // if (signedOnly) { // 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, final ICryptoCallback callback) throws RemoteException { + final AppSettings settings = getAppSettings(); + Runnable r = new Runnable() { @Override public void run() { try { - encryptSafe(inputBytes, encryptionUserIds, callback); + encryptSafe(inputBytes, encryptionUserIds, settings, callback); } catch (RemoteException e) { Log.e(Constants.TAG, "CryptoService", e); } @@ -330,6 +348,23 @@ public class CryptoService extends Service { 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. * diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index 6a4c8a0af..343e5fbc3 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -178,7 +178,7 @@ public class PassphraseCacheService extends Service { } masterKeyId = masterKey.getKeyID(); } - Log.d(TAG, "getCachedPassphraseImpl() for masterKeyId" + masterKeyId); + Log.d(TAG, "getCachedPassphraseImpl() for masterKeyId " + masterKeyId); // get cached passphrase String cachedPassphrase = mPassphraseCache.get(masterKeyId); -- cgit v1.2.3