aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java
diff options
context:
space:
mode:
authormar-v-in <github@rvin.mooo.com>2014-06-08 21:30:11 +0200
committermar-v-in <github@rvin.mooo.com>2014-06-08 21:30:11 +0200
commit08d63340c92d6c251f082a0d200df8541a42ba61 (patch)
treebc22808670b775ec8d97b90d4f3c418d8047e20a /OpenKeychain/src/main/java
parent90f9646f2554c48b1d346e68374dbe943ab8aa9f (diff)
downloadopen-keychain-08d63340c92d6c251f082a0d200df8541a42ba61.tar.gz
open-keychain-08d63340c92d6c251f082a0d200df8541a42ba61.tar.bz2
open-keychain-08d63340c92d6c251f082a0d200df8541a42ba61.zip
Modify KeychainIntentService to support I/O with URIs, allow input and output to/from different types (eg. encrypt file and return byte array)
Diffstat (limited to 'OpenKeychain/src/main/java')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java277
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java2
5 files changed, 109 insertions, 176 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
index 27f41e3d2..67aa8d8c1 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -107,9 +107,11 @@ public class KeychainIntentService extends IntentService
// encrypt, decrypt, import export
public static final String TARGET = "target";
+ public static final String SOURCE = "source";
// possible targets:
- public static final int TARGET_BYTES = 1;
- public static final int TARGET_URI = 2;
+ public static final int IO_BYTES = 1;
+ public static final int IO_FILE = 2; // This was misleadingly TARGET_URI before!
+ public static final int IO_URI = 3;
// encrypt
public static final String ENCRYPT_SIGNATURE_KEY_ID = "secret_key_id";
@@ -118,7 +120,9 @@ public class KeychainIntentService extends IntentService
public static final String ENCRYPT_COMPRESSION_ID = "compression_id";
public static final String ENCRYPT_MESSAGE_BYTES = "message_bytes";
public static final String ENCRYPT_INPUT_FILE = "input_file";
+ public static final String ENCRYPT_INPUT_URI = "input_uri";
public static final String ENCRYPT_OUTPUT_FILE = "output_file";
+ public static final String ENCRYPT_OUTPUT_URI = "output_uri";
public static final String ENCRYPT_SYMMETRIC_PASSPHRASE = "passphrase";
// decrypt/verify
@@ -230,7 +234,7 @@ public class KeychainIntentService extends IntentService
if (ACTION_ENCRYPT_SIGN.equals(action)) {
try {
/* Input */
- int target = data.getInt(TARGET);
+ int source = data.get(SOURCE) != null ? data.getInt(SOURCE) : data.getInt(TARGET);
long signatureKeyId = data.getLong(ENCRYPT_SIGNATURE_KEY_ID);
String symmetricPassphrase = data.getString(ENCRYPT_SYMMETRIC_PASSPHRASE);
@@ -238,71 +242,8 @@ public class KeychainIntentService extends IntentService
boolean useAsciiArmor = data.getBoolean(ENCRYPT_USE_ASCII_ARMOR);
long encryptionKeyIds[] = data.getLongArray(ENCRYPT_ENCRYPTION_KEYS_IDS);
int compressionId = data.getInt(ENCRYPT_COMPRESSION_ID);
- InputStream inStream;
- long inLength;
- InputData inputData;
- OutputStream outStream;
-// String streamFilename = null;
- switch (target) {
- case TARGET_BYTES: /* encrypting bytes directly */
- byte[] bytes = data.getByteArray(ENCRYPT_MESSAGE_BYTES);
-
- inStream = new ByteArrayInputStream(bytes);
- inLength = bytes.length;
-
- inputData = new InputData(inStream, inLength);
- outStream = new ByteArrayOutputStream();
-
- break;
- case TARGET_URI: /* encrypting file */
- String inputFile = data.getString(ENCRYPT_INPUT_FILE);
- String outputFile = data.getString(ENCRYPT_OUTPUT_FILE);
-
- // check if storage is ready
- if (!FileHelper.isStorageMounted(inputFile)
- || !FileHelper.isStorageMounted(outputFile)) {
- throw new PgpGeneralException(
- getString(R.string.error_external_storage_not_ready));
- }
-
- inStream = new FileInputStream(inputFile);
- File file = new File(inputFile);
- inLength = file.length();
- inputData = new InputData(inStream, inLength);
-
- outStream = new FileOutputStream(outputFile);
-
- break;
-
- // TODO: not used currently
-// case TARGET_STREAM: /* Encrypting stream from content uri */
-// Uri providerUri = (Uri) data.getParcelable(ENCRYPT_PROVIDER_URI);
-//
-// // InputStream
-// InputStream in = getContentResolver().openInputStream(providerUri);
-// inLength = PgpHelper.getLengthOfStream(in);
-// inputData = new InputData(in, inLength);
-//
-// // OutputStream
-// try {
-// while (true) {
-// streamFilename = PgpHelper.generateRandomFilename(32);
-// if (streamFilename == null) {
-// throw new PgpGeneralException("couldn't generate random file name");
-// }
-// openFileInput(streamFilename).close();
-// }
-// } catch (FileNotFoundException e) {
-// // found a name that isn't used yet
-// }
-// outStream = openFileOutput(streamFilename, Context.MODE_PRIVATE);
-//
-// break;
-
- default:
- throw new PgpGeneralException("No target choosen!");
-
- }
+ InputData inputData = createEncryptInputData(data);
+ OutputStream outStream = createCryptOutputStream(data);
/* Operation */
PgpSignEncrypt.Builder builder =
@@ -327,7 +268,7 @@ public class KeychainIntentService extends IntentService
PassphraseCacheService.getCachedPassphrase(this, signatureKeyId));
// this assumes that the bytes are cleartext (valid for current implementation!)
- if (target == TARGET_BYTES) {
+ if (source == IO_BYTES) {
builder.setCleartextInput(true);
}
@@ -338,24 +279,7 @@ public class KeychainIntentService extends IntentService
/* Output */
Bundle resultData = new Bundle();
-
- switch (target) {
- case TARGET_BYTES:
- byte output[] = ((ByteArrayOutputStream) outStream).toByteArray();
-
- resultData.putByteArray(RESULT_BYTES, output);
-
- break;
- case TARGET_URI:
- // nothing, file was written, just send okay
-
- break;
-// case TARGET_STREAM:
-// String uri = DataStream.buildDataStreamUri(streamFilename).toString();
-// resultData.putString(RESULT_URI, uri);
-//
-// break;
- }
+ finalizeEncryptOutputStream(data, resultData, outStream);
OtherHelper.logDebugBundle(resultData, "resultData");
@@ -366,78 +290,10 @@ public class KeychainIntentService extends IntentService
} else if (ACTION_DECRYPT_VERIFY.equals(action)) {
try {
/* Input */
- int target = data.getInt(TARGET);
-
- byte[] bytes = data.getByteArray(DECRYPT_CIPHERTEXT_BYTES);
String passphrase = data.getString(DECRYPT_PASSPHRASE);
- InputStream inStream;
- long inLength;
- InputData inputData;
- OutputStream outStream;
- String streamFilename = null;
- switch (target) {
- case TARGET_BYTES: /* decrypting bytes directly */
- inStream = new ByteArrayInputStream(bytes);
- inLength = bytes.length;
-
- inputData = new InputData(inStream, inLength);
- outStream = new ByteArrayOutputStream();
-
- break;
-
- case TARGET_URI: /* decrypting file */
- String inputFile = data.getString(ENCRYPT_INPUT_FILE);
- String outputFile = data.getString(ENCRYPT_OUTPUT_FILE);
-
- // check if storage is ready
- if (!FileHelper.isStorageMounted(inputFile)
- || !FileHelper.isStorageMounted(outputFile)) {
- throw new PgpGeneralException(
- getString(R.string.error_external_storage_not_ready));
- }
-
- // InputStream
- inLength = -1;
- inStream = new FileInputStream(inputFile);
- File file = new File(inputFile);
- inLength = file.length();
- inputData = new InputData(inStream, inLength);
-
- // OutputStream
- outStream = new FileOutputStream(outputFile);
-
- break;
-
- // TODO: not used, maybe contains code useful for new decrypt method for files?
-// case TARGET_STREAM: /* decrypting stream from content uri */
-// Uri providerUri = (Uri) data.getParcelable(ENCRYPT_PROVIDER_URI);
-//
-// // InputStream
-// InputStream in = getContentResolver().openInputStream(providerUri);
-// inLength = PgpHelper.getLengthOfStream(in);
-// inputData = new InputData(in, inLength);
-//
-// // OutputStream
-// try {
-// while (true) {
-// streamFilename = PgpHelper.generateRandomFilename(32);
-// if (streamFilename == null) {
-// throw new PgpGeneralException("couldn't generate random file name");
-// }
-// openFileInput(streamFilename).close();
-// }
-// } catch (FileNotFoundException e) {
-// // found a name that isn't used yet
-// }
-// outStream = openFileOutput(streamFilename, Context.MODE_PRIVATE);
-//
-// break;
-
- default:
- throw new PgpGeneralException("No target choosen!");
-
- }
+ InputData inputData = createDecryptInputData(data);
+ OutputStream outStream = createCryptOutputStream(data);
/* Operation */
@@ -468,21 +324,7 @@ public class KeychainIntentService extends IntentService
/* Output */
- switch (target) {
- case TARGET_BYTES:
- byte output[] = ((ByteArrayOutputStream) outStream).toByteArray();
- resultData.putByteArray(RESULT_DECRYPTED_BYTES, output);
- break;
- case TARGET_URI:
- // nothing, file was written, just send okay and verification bundle
-
- break;
-// case TARGET_STREAM:
-// String uri = DataStream.buildDataStreamUri(streamFilename).toString();
-// resultData.putString(RESULT_URI, uri);
-//
-// break;
- }
+ finalizeDecryptOutputStream(data, resultData, outStream);
OtherHelper.logDebugBundle(resultData, "resultData");
@@ -915,4 +757,95 @@ public class KeychainIntentService extends IntentService
public boolean hasServiceStopped() {
return mIsCanceled;
}
+
+ private InputData createDecryptInputData(Bundle data) throws IOException, PgpGeneralException {
+ return createCryptInputData(data, DECRYPT_CIPHERTEXT_BYTES);
+ }
+
+ private InputData createEncryptInputData(Bundle data) throws IOException, PgpGeneralException {
+ return createCryptInputData(data, ENCRYPT_MESSAGE_BYTES);
+ }
+
+ private InputData createCryptInputData(Bundle data, String bytesName) throws PgpGeneralException, IOException {
+ int source = data.get(SOURCE) != null ? data.getInt(SOURCE) : data.getInt(TARGET);
+ switch (source) {
+ case IO_BYTES: /* encrypting bytes directly */
+ byte[] bytes = data.getByteArray(bytesName);
+ return new InputData(new ByteArrayInputStream(bytes), bytes.length);
+
+ case IO_FILE: /* encrypting file */
+ String inputFile = data.getString(ENCRYPT_INPUT_FILE);
+
+ // check if storage is ready
+ if (!FileHelper.isStorageMounted(inputFile)) {
+ throw new PgpGeneralException(getString(R.string.error_external_storage_not_ready));
+ }
+
+ return new InputData(new FileInputStream(inputFile), new File(inputFile).length());
+
+ case IO_URI: /* encrypting content uri */
+ Uri providerUri = data.getParcelable(ENCRYPT_INPUT_URI);
+
+ // InputStream
+ InputStream in = getContentResolver().openInputStream(providerUri);
+ return new InputData(in, PgpHelper.getLengthOfStream(in));
+
+ default:
+ throw new PgpGeneralException("No target choosen!");
+ }
+ }
+
+ private OutputStream createCryptOutputStream(Bundle data) throws PgpGeneralException, FileNotFoundException {
+ int target = data.getInt(TARGET);
+ switch (target) {
+ case IO_BYTES:
+ return new ByteArrayOutputStream();
+
+ case IO_FILE:
+ String outputFile = data.getString(ENCRYPT_OUTPUT_FILE);
+
+ // check if storage is ready
+ if (!FileHelper.isStorageMounted(outputFile)) {
+ throw new PgpGeneralException(
+ getString(R.string.error_external_storage_not_ready));
+ }
+
+ // OutputStream
+ return new FileOutputStream(outputFile);
+
+ case IO_URI:
+ Uri providerUri = data.getParcelable(ENCRYPT_OUTPUT_URI);
+
+ return getContentResolver().openOutputStream(providerUri);
+
+ default:
+ throw new PgpGeneralException("No target choosen!");
+ }
+ }
+
+ private void finalizeEncryptOutputStream(Bundle data, Bundle resultData, OutputStream outStream) {
+ finalizeCryptOutputStream(data, resultData, outStream, RESULT_BYTES);
+ }
+
+ private void finalizeDecryptOutputStream(Bundle data, Bundle resultData, OutputStream outStream) {
+ finalizeCryptOutputStream(data, resultData, outStream, RESULT_DECRYPTED_BYTES);
+ }
+
+ private void finalizeCryptOutputStream(Bundle data, Bundle resultData, OutputStream outStream, String bytesName) {
+ int target = data.getInt(TARGET);
+ switch (target) {
+ case IO_BYTES:
+ byte output[] = ((ByteArrayOutputStream) outStream).toByteArray();
+ resultData.putByteArray(bytesName, output);
+ break;
+ case IO_FILE:
+ // nothing, file was written, just send okay and verification bundle
+
+ break;
+ case IO_URI:
+ // nothing, output was written, just send okay and verification bundle
+
+ break;
+ }
+ }
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
index d953e2591..2b43ad3bd 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
@@ -170,7 +170,7 @@ public class DecryptFileFragment extends DecryptFragment {
intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY);
// data
- data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI);
+ data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_FILE);
Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename="
+ mOutputFilename);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java
index d1ad7fbc5..46462f924 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java
@@ -129,7 +129,7 @@ public class DecryptMessageFragment extends DecryptFragment {
intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY);
// data
- data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES);
+ data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_BYTES);
data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, mCiphertext.getBytes());
data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, passphrase);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java
index d150abdeb..7df6b2134 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java
@@ -280,7 +280,7 @@ public class EncryptFileFragment extends Fragment {
// fill values for this action
Bundle data = new Bundle();
- data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI);
+ data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_FILE);
if (mEncryptInterface.isModeSymmetric()) {
Log.d(Constants.TAG, "Symmetric encryption enabled!");
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java
index 4c35806e5..8a6103b16 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java
@@ -177,7 +177,7 @@ public class EncryptMessageFragment extends Fragment {
// fill values for this action
Bundle data = new Bundle();
- data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES);
+ data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_BYTES);
String message = mMessage.getText().toString();