aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThialfihar <thialfihar@gmail.com>2010-07-09 11:28:39 +0000
committerThialfihar <thialfihar@gmail.com>2010-07-09 11:28:39 +0000
commit3ac472125a7ad3b7b600c32129a50def3b8a1b8a (patch)
tree94c4bab7ce686dd048e132eea57cff2c950ee03a /src
parentf03b34905724f6f1fbdad03c974d29b730a7d827 (diff)
downloadopen-keychain-3ac472125a7ad3b7b600c32129a50def3b8a1b8a.tar.gz
open-keychain-3ac472125a7ad3b7b600c32129a50def3b8a1b8a.tar.bz2
open-keychain-3ac472125a7ad3b7b600c32129a50def3b8a1b8a.zip
some playing with content stream decryption and providing the result as content stream
Diffstat (limited to 'src')
-rw-r--r--src/org/thialfihar/android/apg/Apg.java43
-rw-r--r--src/org/thialfihar/android/apg/DecryptActivity.java90
-rw-r--r--src/org/thialfihar/android/apg/provider/DataProvider.java18
3 files changed, 116 insertions, 35 deletions
diff --git a/src/org/thialfihar/android/apg/Apg.java b/src/org/thialfihar/android/apg/Apg.java
index b2ae19368..d606a553c 100644
--- a/src/org/thialfihar/android/apg/Apg.java
+++ b/src/org/thialfihar/android/apg/Apg.java
@@ -37,7 +37,6 @@ import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.regex.Pattern;
@@ -118,7 +117,8 @@ public class Apg {
public static final String EXTRA_STATUS = "status";
public static final String EXTRA_ERROR = "error";
public static final String EXTRA_DECRYPTED_MESSAGE = "decryptedMessage";
- public static final String EXTRA_ENCRYPTED_MESSAGE = "decryptedMessage";
+ public static final String EXTRA_ENCRYPTED_MESSAGE = "encryptedMessage";
+ public static final String EXTRA_RESULT_URI = "resultUri";
public static final String EXTRA_SIGNATURE = "signature";
public static final String EXTRA_SIGNATURE_KEY_ID = "signatureKeyId";
public static final String EXTRA_SIGNATURE_USER_ID = "signatureUserId";
@@ -1851,4 +1851,43 @@ public class Apg {
public static String getFullVersion(Context context) {
return "APG v" + getVersion(context);
}
+
+ public static String generateRandomString(int length) {
+ SecureRandom random = new SecureRandom();
+ /*
+ try {
+ random = SecureRandom.getInstance("SHA1PRNG", new BouncyCastleProvider());
+ } catch (NoSuchAlgorithmException e) {
+ // TODO: need to handle this case somehow
+ return null;
+ }*/
+ byte bytes[] = new byte[length];
+ random.nextBytes(bytes);
+ String result = "";
+ for (int i = 0; i < length; ++i) {
+ int v = ((int)bytes[i] + 256) % 64;
+ if (v < 10) {
+ result += (char)((int)'0' + v);
+ } else if (v < 36) {
+ result += (char)((int)'A' + v - 10);
+ } else if (v < 62) {
+ result += (char)((int)'a' + v - 36);
+ } else if (v == 62) {
+ result += '_';
+ } else if (v == 63) {
+ result += '.';
+ }
+ }
+ return result;
+ }
+
+ static long getLengthOfStream(InputStream in) throws IOException {
+ long size = 0;
+ long n = 0;
+ byte dummy[] = new byte[0x10000];
+ while ((n = in.read(dummy)) > 0) {
+ size += n;
+ }
+ return size;
+ }
}
diff --git a/src/org/thialfihar/android/apg/DecryptActivity.java b/src/org/thialfihar/android/apg/DecryptActivity.java
index 98480bbf7..571edbdf5 100644
--- a/src/org/thialfihar/android/apg/DecryptActivity.java
+++ b/src/org/thialfihar/android/apg/DecryptActivity.java
@@ -31,6 +31,7 @@ import java.util.regex.Matcher;
import org.bouncycastle2.jce.provider.BouncyCastleProvider;
import org.bouncycastle2.openpgp.PGPException;
+import org.thialfihar.android.apg.provider.DataProvider;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
@@ -86,6 +87,8 @@ public class DecryptActivity extends BaseActivity {
private String mInputFilename = null;
private String mOutputFilename = null;
+ private Uri mContentUri = null;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -220,26 +223,29 @@ public class DecryptActivity extends BaseActivity {
mSource.showNext();
}
} else if (Apg.Intent.DECRYPT_AND_RETURN.equals(mIntent.getAction())) {
- Bundle extras = mIntent.getExtras();
- if (extras == null) {
- extras = new Bundle();
- }
- String data = extras.getString(Apg.EXTRA_TEXT);
- if (data != null) {
- Matcher matcher = Apg.PGP_MESSAGE.matcher(data);
- if (matcher.matches()) {
- data = matcher.group(1);
- // replace non breakable spaces
- data = data.replaceAll("\\xa0", " ");
- mMessage.setText(data);
- } else {
- matcher = Apg.PGP_SIGNED_MESSAGE.matcher(data);
+ mContentUri = mIntent.getData();
+ if (mContentUri == null) {
+ Bundle extras = mIntent.getExtras();
+ if (extras == null) {
+ extras = new Bundle();
+ }
+ String data = extras.getString(Apg.EXTRA_TEXT);
+ if (data != null) {
+ Matcher matcher = Apg.PGP_MESSAGE.matcher(data);
if (matcher.matches()) {
data = matcher.group(1);
// replace non breakable spaces
data = data.replaceAll("\\xa0", " ");
mMessage.setText(data);
- mDecryptButton.setText(R.string.btn_verify);
+ } else {
+ matcher = Apg.PGP_SIGNED_MESSAGE.matcher(data);
+ if (matcher.matches()) {
+ data = matcher.group(1);
+ // replace non breakable spaces
+ data = data.replaceAll("\\xa0", " ");
+ mMessage.setText(data);
+ mDecryptButton.setText(R.string.btn_verify);
+ }
}
}
}
@@ -393,7 +399,9 @@ public class DecryptActivity extends BaseActivity {
String error = null;
try {
InputStream in;
- if (mDecryptTarget == Id.target.file) {
+ if (mContentUri != null) {
+ in = getContentResolver().openInputStream(mContentUri);
+ } else if (mDecryptTarget == Id.target.file) {
if (mInputFilename.startsWith("file")) {
in = new FileInputStream(mInputFilename);
} else {
@@ -412,7 +420,9 @@ public class DecryptActivity extends BaseActivity {
setSecretKeyId(Id.key.symmetric);
// look at the file/message again to check whether there's
// symmetric encryption data in there
- if (mDecryptTarget == Id.target.file) {
+ if (mContentUri != null) {
+ in = getContentResolver().openInputStream(mContentUri);
+ } else if (mDecryptTarget == Id.target.file) {
if (mInputFilename.startsWith("file")) {
in = new FileInputStream(mInputFilename);
} else {
@@ -494,22 +504,32 @@ public class DecryptActivity extends BaseActivity {
try {
PositionAwareInputStream in = null;
OutputStream out = null;
+ String randomString = null;
long size = 0;
- if (mDecryptTarget == Id.target.message) {
+ if (mContentUri != null) {
+ in = new PositionAwareInputStream(getContentResolver().openInputStream(mContentUri));
+ size = Apg.getLengthOfStream(getContentResolver().openInputStream(mContentUri));
+ try {
+ while (true) {
+ randomString = Apg.generateRandomString(32);
+ if (randomString == null) {
+ throw new Apg.GeneralException("couldn't generate random file name");
+ }
+ this.openFileInput(randomString).close();
+ }
+ } catch (FileNotFoundException e) {
+ // found a name that isn't used yet
+ }
+ out = openFileOutput(randomString, MODE_PRIVATE);
+ } else if (mDecryptTarget == Id.target.message) {
String messageData = mMessage.getText().toString();
in = new PositionAwareInputStream(new ByteArrayInputStream(messageData.getBytes()));
out = new ByteArrayOutputStream();
size = messageData.getBytes().length;
} else {
if (mInputFilename.startsWith("content")) {
- InputStream tmp = getContentResolver().openInputStream(Uri.parse(mInputFilename));
- size = 0;
- long n = 0;
- byte dummy[] = new byte[0x10000];
- while ((n = tmp.read(dummy)) > 0) {
- size += n;
- }
+ size = Apg.getLengthOfStream(getContentResolver().openInputStream(Uri.parse(mInputFilename)));
in = new PositionAwareInputStream(
getContentResolver().openInputStream(Uri.parse(mInputFilename)));
} else {
@@ -528,7 +548,10 @@ public class DecryptActivity extends BaseActivity {
}
out.close();
- if (mDecryptTarget == Id.target.message) {
+
+ if (randomString != null) {
+ data.putString(Apg.EXTRA_RESULT_URI, "content://" + DataProvider.AUTHORITY + "/data/" + randomString);
+ } else if (mDecryptTarget == Id.target.message) {
data.putString(Apg.EXTRA_DECRYPTED_MESSAGE,
new String(((ByteArrayOutputStream) out).toByteArray()));
}
@@ -570,6 +593,14 @@ public class DecryptActivity extends BaseActivity {
}
Toast.makeText(this, R.string.decryptionSuccessful, Toast.LENGTH_SHORT).show();
+ if (mReturnResult) {
+ Intent intent = new Intent();
+ intent.putExtras(data);
+ setResult(RESULT_OK, intent);
+ finish();
+ return;
+ }
+
switch (mDecryptTarget) {
case Id.target.message: {
String decryptedMessage = data.getString(Apg.EXTRA_DECRYPTED_MESSAGE);
@@ -616,13 +647,6 @@ public class DecryptActivity extends BaseActivity {
}
mSignatureLayout.setVisibility(View.VISIBLE);
}
-
- if (mReturnResult) {
- Intent intent = new Intent();
- intent.putExtras(data);
- setResult(RESULT_OK, intent);
- finish();
- }
}
@Override
diff --git a/src/org/thialfihar/android/apg/provider/DataProvider.java b/src/org/thialfihar/android/apg/provider/DataProvider.java
index 0a4bfbad4..9cf083528 100644
--- a/src/org/thialfihar/android/apg/provider/DataProvider.java
+++ b/src/org/thialfihar/android/apg/provider/DataProvider.java
@@ -16,6 +16,8 @@
package org.thialfihar.android.apg.provider;
+import java.io.File;
+import java.io.FileNotFoundException;
import java.util.HashMap;
import org.thialfihar.android.apg.Id;
@@ -27,6 +29,7 @@ import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
+import android.os.ParcelFileDescriptor;
import android.text.TextUtils;
public class DataProvider extends ContentProvider {
@@ -50,6 +53,8 @@ public class DataProvider extends ContentProvider {
private static final int SECRET_KEY_RING_USER_ID = 221;
private static final int SECRET_KEY_RING_USER_ID_RANK = 222;
+ private static final int DATA_STREAM = 301;
+
private static final String PUBLIC_KEY_RING_CONTENT_DIR_TYPE =
"vnd.android.cursor.dir/vnd.thialfihar.apg.public.key_ring";
private static final String PUBLIC_KEY_RING_CONTENT_ITEM_TYPE =
@@ -109,6 +114,8 @@ public class DataProvider extends ContentProvider {
mUriMatcher.addURI(AUTHORITY, "key_rings/secret", SECRET_KEY_RING);
mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*", SECRET_KEY_RING_ID);
+
+ mUriMatcher.addURI(AUTHORITY, "data/*", DATA_STREAM);
}
@Override
@@ -360,4 +367,15 @@ public class DataProvider extends ContentProvider {
// not supported
return 0;
}
+
+ @Override
+ public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+ int match = mUriMatcher.match(uri);
+ if (match != DATA_STREAM) {
+ throw new FileNotFoundException();
+ }
+ String fileName = uri.getPathSegments().get(1);
+ File file = new File(getContext().getFilesDir().getAbsolutePath(), fileName);
+ return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
+ }
}