diff options
Diffstat (limited to 'OpenPGP-Keychain')
3 files changed, 101 insertions, 26 deletions
diff --git a/OpenPGP-Keychain/src/org/openintents/crypto/ICryptoService.aidl b/OpenPGP-Keychain/src/org/openintents/crypto/ICryptoService.aidl index 04c8eb30e..53f39dffc 100644 --- a/OpenPGP-Keychain/src/org/openintents/crypto/ICryptoService.aidl +++ b/OpenPGP-Keychain/src/org/openintents/crypto/ICryptoService.aidl @@ -37,30 +37,30 @@ interface ICryptoService { oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in ICryptoCallback callback); /** - * Encrypt and sign + * Sign * * @param inputBytes * Byte array you want to encrypt - * @param encryptionUserIds - * User Ids (emails) of recipients * @param signatureUserId * User Ids (email) of sender * @param callback * Callback where to return results */ - oneway void encryptAndSign(in byte[] inputBytes, in String[] encryptionUserIds, String signatureUserId, in ICryptoCallback callback); + oneway void sign(in byte[] inputBytes, String signatureUserId, in ICryptoCallback callback); /** - * Sign + * Encrypt and sign * * @param inputBytes * Byte array you want to encrypt + * @param encryptionUserIds + * User Ids (emails) of recipients * @param signatureUserId * User Ids (email) of sender * @param callback * Callback where to return results */ - oneway void sign(in byte[] inputBytes, String signatureUserId, in ICryptoCallback callback); + oneway void encryptAndSign(in byte[] inputBytes, in String[] encryptionUserIds, String signatureUserId, in ICryptoCallback callback); /** * Decrypts and verifies given input bytes. If no signature is present this method diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/crypto_provider/CryptoService.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/crypto_provider/CryptoService.java index a70641b58..7ff8c0e3e 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/crypto_provider/CryptoService.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/crypto_provider/CryptoService.java @@ -56,8 +56,6 @@ public class CryptoService extends Service { PausableThreadPoolExecutor mThreadPool = new PausableThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, mPoolQueue); - private ArrayList<String> mAllowedPackages; - public static final String ACTION_SERVICE_ACTIVITY = "org.sufficientlysecure.keychain.crypto_provider.IServiceActivityCallback"; @Override @@ -65,10 +63,6 @@ public class CryptoService extends Service { super.onCreate(); mContext = this; Log.d(Constants.TAG, "CryptoService, onCreate()"); - - // load allowed packages from database - mAllowedPackages = ProviderHelper.getCryptoConsumers(mContext); - Log.d(Constants.TAG, "allowed: " + mAllowedPackages); } @Override @@ -95,6 +89,40 @@ public class CryptoService extends Service { } } + private synchronized void encryptSafe(byte[] inputBytes, String[] encryptionUserIds, + 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(); + + // TODO: hardcoded... + boolean useAsciiArmor = true; + int compressionId = 2; // zlib + + // 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)); + + outStream.close(); + } catch (Exception e) { + Log.e(Constants.TAG, "KeychainService, Exception!", e); + + try { + callback.onError(new CryptoError(0, e.getMessage())); + } catch (Exception t) { + Log.e(Constants.TAG, "Error returning exception to client", t); + } + } + } + private synchronized void decryptAndVerifySafe(byte[] inputBytes, ICryptoCallback callback) throws RemoteException { try { @@ -171,10 +199,22 @@ public class CryptoService extends Service { private final ICryptoService.Stub mBinder = new ICryptoService.Stub() { @Override - public void encrypt(byte[] inputBytes, String[] encryptionUserIds, ICryptoCallback callback) - throws RemoteException { - // TODO Auto-generated method stub + public void encrypt(final byte[] inputBytes, final String[] encryptionUserIds, + final ICryptoCallback callback) throws RemoteException { + Runnable r = new Runnable() { + + @Override + public void run() { + try { + encryptSafe(inputBytes, encryptionUserIds, callback); + } catch (RemoteException e) { + Log.e(Constants.TAG, "CryptoService", e); + } + } + }; + + checkAndEnqueue(r); } @Override @@ -218,9 +258,6 @@ public class CryptoService extends Service { public void register(boolean success, String packageName) throws RemoteException { if (success) { - // reload allowed packages - mAllowedPackages = ProviderHelper.getCryptoConsumers(mContext); - // resume threads if (isPackageAllowed(packageName)) { mThreadPool.resume(); @@ -287,8 +324,11 @@ public class CryptoService extends Service { private boolean isPackageAllowed(String packageName) { Log.d(Constants.TAG, "packageName: " + packageName); + ArrayList<String> allowedPkgs = ProviderHelper.getCryptoConsumers(mContext); + Log.d(Constants.TAG, "allowed: " + allowedPkgs); + // check if package is allowed to use our service - if (mAllowedPackages.contains(packageName)) { + if (allowedPkgs.contains(packageName)) { Log.d(Constants.TAG, "Package is allowed! packageName: " + packageName); return true; diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 70be38e21..a34cda0c3 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de> * Copyright (C) 2010 Thialfihar <thi@thialfihar.org> * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,8 +17,6 @@ package org.sufficientlysecure.keychain.provider; -import java.io.File; -import java.io.FileNotFoundException; import java.util.Arrays; import java.util.HashMap; @@ -44,7 +42,6 @@ import android.database.sqlite.SQLiteConstraintException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; -import android.os.ParcelFileDescriptor; import android.provider.BaseColumns; import android.text.TextUtils; @@ -82,6 +79,7 @@ public class KeychainProvider extends ContentProvider { private static final int SECRET_KEY_RING_USER_ID_BY_ROW_ID = 222; private static final int CRYPTO_CONSUMERS = 301; + private static final int CRYPTO_CONSUMERS_BY_ROW_ID = 302; // private static final int DATA_STREAM = 401; @@ -230,6 +228,8 @@ public class KeychainProvider extends ContentProvider { * Crypto Consumers */ matcher.addURI(authority, KeychainContract.BASE_CRYPTO_CONSUMERS, CRYPTO_CONSUMERS); + matcher.addURI(authority, KeychainContract.BASE_CRYPTO_CONSUMERS + "/#", + CRYPTO_CONSUMERS_BY_ROW_ID); /** * data stream @@ -293,6 +293,9 @@ public class KeychainProvider extends ContentProvider { case CRYPTO_CONSUMERS: return CryptoConsumers.CONTENT_TYPE; + case CRYPTO_CONSUMERS_BY_ROW_ID: + return CryptoConsumers.CONTENT_ITEM_TYPE; + default: throw new UnsupportedOperationException("Unknown uri: " + uri); } @@ -653,6 +656,7 @@ public class KeychainProvider extends ContentProvider { rowId = db.insertOrThrow(Tables.KEY_RINGS, null, values); rowUri = KeyRings.buildPublicKeyRingsUri(Long.toString(rowId)); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_KEY: @@ -660,11 +664,13 @@ public class KeychainProvider extends ContentProvider { rowId = db.insertOrThrow(Tables.KEYS, null, values); rowUri = Keys.buildPublicKeysUri(Long.toString(rowId)); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_USER_ID: rowId = db.insertOrThrow(Tables.USER_IDS, null, values); rowUri = UserIds.buildPublicUserIdsUri(Long.toString(rowId)); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case SECRET_KEY_RING: @@ -672,6 +678,7 @@ public class KeychainProvider extends ContentProvider { rowId = db.insertOrThrow(Tables.KEY_RINGS, null, values); rowUri = KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case SECRET_KEY_RING_KEY: @@ -679,6 +686,7 @@ public class KeychainProvider extends ContentProvider { rowId = db.insertOrThrow(Tables.KEYS, null, values); rowUri = Keys.buildSecretKeysUri(Long.toString(rowId)); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case SECRET_KEY_RING_USER_ID: @@ -697,7 +705,6 @@ public class KeychainProvider extends ContentProvider { // notify of changes in db getContext().getContentResolver().notifyChange(uri, null); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); } catch (SQLiteConstraintException e) { Log.e(Constants.TAG, "Constraint exception on insert! Entry already existing?"); @@ -725,6 +732,7 @@ public class KeychainProvider extends ContentProvider { count = db.delete(Tables.KEY_RINGS, buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection), selectionArgs); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: case SECRET_KEY_RING_BY_MASTER_KEY_ID: @@ -733,24 +741,29 @@ public class KeychainProvider extends ContentProvider { count = db.delete(Tables.KEY_RINGS, buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection), selectionArgs); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_KEY_BY_ROW_ID: case SECRET_KEY_RING_KEY_BY_ROW_ID: count = db.delete(Tables.KEYS, buildDefaultKeysSelection(uri, getKeyType(match), selection), selectionArgs); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: case SECRET_KEY_RING_USER_ID_BY_ROW_ID: count = db.delete(Tables.KEYS, buildDefaultUserIdsSelection(uri, selection), selectionArgs); break; + case CRYPTO_CONSUMERS_BY_ROW_ID: + count = db.delete(Tables.CRYPTO_CONSUMERS, + buildDefaultCryptoConsumersSelection(uri, selection), selectionArgs); + break; default: throw new UnsupportedOperationException("Unknown uri: " + uri); } // notify of changes in db getContext().getContentResolver().notifyChange(uri, null); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); return count; } @@ -776,6 +789,8 @@ public class KeychainProvider extends ContentProvider { values, buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection), selectionArgs); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); + break; case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: case SECRET_KEY_RING_BY_MASTER_KEY_ID: @@ -786,6 +801,8 @@ public class KeychainProvider extends ContentProvider { values, buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection), selectionArgs); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); + break; case PUBLIC_KEY_RING_KEY_BY_ROW_ID: case SECRET_KEY_RING_KEY_BY_ROW_ID: @@ -793,6 +810,8 @@ public class KeychainProvider extends ContentProvider { .update(Tables.KEYS, values, buildDefaultKeysSelection(uri, getKeyType(match), selection), selectionArgs); + sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); + break; case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: case SECRET_KEY_RING_USER_ID_BY_ROW_ID: @@ -805,7 +824,6 @@ public class KeychainProvider extends ContentProvider { // notify of changes in db getContext().getContentResolver().notifyChange(uri, null); - sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); } catch (SQLiteConstraintException e) { Log.e(Constants.TAG, "Constraint exception on update! Entry already existing?"); @@ -888,6 +906,23 @@ public class KeychainProvider extends ContentProvider { return BaseColumns._ID + "=" + rowId + andForeignKeyRing + andSelection; } + /** + * Build default selection statement for Crypto Consumers. If no extra selection is specified + * only build where clause with rowId + * + * @param uri + * @param selection + * @return + */ + private String buildDefaultCryptoConsumersSelection(Uri uri, String selection) { + String andSelection = ""; + if (!TextUtils.isEmpty(selection)) { + andSelection = " AND (" + selection + ")"; + } + + return selection + andSelection; + } + // @Override // public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { // int match = mUriMatcher.match(uri); |