trying to add support for various source and destination modes for encryption and decryption (String, byte[], filename, content stream), also more Intent options added

This commit is contained in:
Thialfihar 2010-07-09 20:55:17 +00:00
parent 3ac472125a
commit 2c47734f0f
15 changed files with 380 additions and 186 deletions

View File

@ -117,7 +117,9 @@ 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_DECRYPTED_DATA = "decryptedData";
public static final String EXTRA_ENCRYPTED_MESSAGE = "encryptedMessage";
public static final String EXTRA_ENCRYPTED_DATA = "encryptedData";
public static final String EXTRA_RESULT_URI = "resultUri";
public static final String EXTRA_SIGNATURE = "signature";
public static final String EXTRA_SIGNATURE_KEY_ID = "signatureKeyId";
@ -135,6 +137,8 @@ public class Apg {
public static final String EXTRA_PROGRESS = "progress";
public static final String EXTRA_MAX = "max";
public static final String EXTRA_ACCOUNT = "account";
public static final String EXTRA_ASCII_ARMOUR = "asciiArmour";
public static final String EXTRA_BINARY = "binary";
public static final String AUTHORITY = DataProvider.AUTHORITY;
@ -576,7 +580,7 @@ public class Apg {
}
public static Bundle importKeyRings(Activity context, int type,
InputStream inStream, long dataLength,
InputData data,
ProgressDialogUpdater progress)
throws GeneralException, FileNotFoundException, PGPException, IOException {
Bundle returnData = new Bundle();
@ -591,7 +595,7 @@ public class Apg {
throw new GeneralException(context.getString(R.string.error_externalStorageNotReady));
}
PositionAwareInputStream progressIn = new PositionAwareInputStream(inStream);
PositionAwareInputStream progressIn = new PositionAwareInputStream(data.getInputStream());
// need to have access to the bufferedInput, so we can reuse it for the possible
// PGPObject chunks after the first one, e.g. files with several consecutive ASCII
// armour blocks
@ -637,7 +641,7 @@ public class Apg {
} else if (retValue == Id.return_value.ok) {
++newKeys;
}
progress.setProgress((int)(100 * progressIn.position() / dataLength), 100);
progress.setProgress((int)(100 * progressIn.position() / data.getSize()), 100);
obj = objectFactory.nextObject();
}
}
@ -1110,8 +1114,7 @@ public class Apg {
}
public static void encrypt(Context context,
InputStream inStream, OutputStream outStream,
long dataLength,
InputData data, OutputStream outStream,
boolean armored,
long encryptionKeyIds[], long signatureKeyId,
String signaturePassPhrase,
@ -1213,14 +1216,15 @@ public class Apg {
long done = 0;
int n = 0;
byte[] buffer = new byte[1 << 16];
while ((n = inStream.read(buffer)) > 0) {
InputStream in = data.getInputStream();
while ((n = in.read(buffer)) > 0) {
pOut.write(buffer, 0, n);
if (signatureKeyId != 0) {
signatureGenerator.update(buffer, 0, n);
}
done += n;
if (dataLength != 0) {
progress.setProgress((int) (20 + (95 - 20) * done / dataLength), 100);
if (data.getSize() != 0) {
progress.setProgress((int) (20 + (95 - 20) * done / data.getSize()), 100);
}
}
@ -1242,7 +1246,7 @@ public class Apg {
}
public static void signText(Context context,
InputStream inStream, OutputStream outStream,
InputData data, OutputStream outStream,
long signatureKeyId, String signaturePassPhrase,
int hashAlgorithm,
ProgressDialogUpdater progress)
@ -1294,6 +1298,7 @@ public class Apg {
armorOut.beginClearText(hashAlgorithm);
ByteArrayOutputStream lineOut = new ByteArrayOutputStream();
InputStream inStream = data.getInputStream();
int lookAhead = readInputLine(lineOut, inStream);
processLine(armorOut, signatureGenerator, lineOut.toByteArray());
@ -1319,9 +1324,9 @@ public class Apg {
progress.setProgress(R.string.progress_done, 100, 100);
}
public static long getDecryptionKeyId(Context context, InputStream inStream)
public static long getDecryptionKeyId(Context context, InputData data)
throws GeneralException, NoAsymmetricEncryptionException, IOException {
InputStream in = PGPUtil.getDecoderStream(inStream);
InputStream in = PGPUtil.getDecoderStream(data.getInputStream());
PGPObjectFactory pgpF = new PGPObjectFactory(in);
PGPEncryptedDataList enc;
Object o = pgpF.nextObject();
@ -1365,9 +1370,9 @@ public class Apg {
return secretKey.getKeyID();
}
public static boolean hasSymmetricEncryption(Context context, InputStream inStream)
public static boolean hasSymmetricEncryption(Context context, InputData data)
throws GeneralException, IOException {
InputStream in = PGPUtil.getDecoderStream(inStream);
InputStream in = PGPUtil.getDecoderStream(data.getInputStream());
PGPObjectFactory pgpF = new PGPObjectFactory(in);
PGPEncryptedDataList enc;
Object o = pgpF.nextObject();
@ -1395,8 +1400,7 @@ public class Apg {
}
public static Bundle decrypt(Context context,
PositionAwareInputStream inStream, OutputStream outStream,
long dataLength,
InputData data, OutputStream outStream,
String passPhrase, ProgressDialogUpdater progress,
boolean assumeSymmetric)
throws IOException, GeneralException, PGPException, SignatureException {
@ -1404,7 +1408,7 @@ public class Apg {
passPhrase = "";
}
Bundle returnData = new Bundle();
InputStream in = PGPUtil.getDecoderStream(inStream);
InputStream in = PGPUtil.getDecoderStream(data.getInputStream());
PGPObjectFactory pgpF = new PGPObjectFactory(in);
PGPEncryptedDataList enc;
Object o = pgpF.nextObject();
@ -1557,7 +1561,7 @@ public class Apg {
}
int n = 0;
int done = 0;
long startPos = inStream.position();
long startPos = data.getStreamPosition();
while ((n = dataIn.read(buffer)) > 0) {
out.write(buffer, 0, n);
done += n;
@ -1571,11 +1575,11 @@ public class Apg {
}
// unknown size, but try to at least have a moving, slowing down progress bar
currentProgress = startProgress + (endProgress - startProgress) * done / (done + 100000);
if (dataLength - startPos == 0) {
if (data.getSize() - startPos == 0) {
currentProgress = endProgress;
} else {
currentProgress = (int)(startProgress + (endProgress - startProgress) *
(inStream.position() - startPos) / (dataLength - startPos));
(data.getStreamPosition() - startPos) / (data.getSize() - startPos));
}
progress.setProgress(currentProgress, 100);
}
@ -1609,13 +1613,13 @@ public class Apg {
}
public static Bundle verifyText(Context context,
InputStream inStream, OutputStream outStream,
InputData data, OutputStream outStream,
ProgressDialogUpdater progress)
throws IOException, GeneralException, PGPException, SignatureException {
Bundle returnData = new Bundle();
ByteArrayOutputStream out = new ByteArrayOutputStream();
ArmoredInputStream aIn = new ArmoredInputStream(inStream);
ArmoredInputStream aIn = new ArmoredInputStream(data.getInputStream());
progress.setProgress(R.string.progress_done, 0, 100);

View File

@ -0,0 +1,79 @@
package org.thialfihar.android.apg;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.thialfihar.android.apg.Apg.GeneralException;
import android.content.Context;
import android.os.Environment;
public class DataDestination {
private String mStreamFilename;
private String mFilename;
private int mMode = Id.mode.undefined;
public DataDestination() {
}
public void setMode(int mode) {
mMode = mode;
}
public void setFilename(String filename) {
mFilename = filename;
}
public String getStreamFilename() {
return mStreamFilename;
}
protected OutputStream getOutputStream(Context context)
throws Apg.GeneralException, FileNotFoundException, IOException {
OutputStream out = null;
mStreamFilename = null;
switch (mMode) {
case Id.mode.stream: {
try {
while (true) {
mStreamFilename = Apg.generateRandomString(32);
if (mStreamFilename == null) {
throw new Apg.GeneralException("couldn't generate random file name");
}
context.openFileInput(mStreamFilename).close();
}
} catch (FileNotFoundException e) {
// found a name that isn't used yet
}
out = context.openFileOutput(mStreamFilename, Context.MODE_PRIVATE);
break;
}
case Id.mode.byte_array: {
out = new ByteArrayOutputStream();
break;
}
case Id.mode.file: {
if (mFilename.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
throw new GeneralException(context.getString(R.string.error_externalStorageNotReady));
}
}
out = new FileOutputStream(mFilename);
break;
}
default: {
break;
}
}
return out;
}
}

View File

@ -0,0 +1,88 @@
package org.thialfihar.android.apg;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.thialfihar.android.apg.Apg.GeneralException;
import android.content.Context;
import android.net.Uri;
import android.os.Environment;
public class DataSource {
private Uri mContentUri = null;
private String mText = null;
private byte[] mData = null;
public DataSource() {
}
public void setUri(Uri uri) {
mContentUri = uri;
}
public void setUri(String uri) {
if (uri.startsWith("/")) {
setUri(Uri.parse("file://" + uri));
} else {
setUri(Uri.parse(uri));
}
}
public void setText(String text) {
mText = text;
}
public void setData(byte[] data) {
mData = data;
}
public InputData getInputData(Context context, boolean withSize)
throws GeneralException, FileNotFoundException, IOException {
InputStream in = null;
long size = 0;
if (mContentUri != null) {
if (mContentUri.getScheme().equals("file")) {
// get the rest after "file://"
String path = mContentUri.toString().substring(6);
if (path.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
throw new GeneralException(context.getString(R.string.error_externalStorageNotReady));
}
}
in = new FileInputStream(path);
File file = new File(path);
if (withSize) {
size = file.length();
}
} else {
in = context.getContentResolver().openInputStream(mContentUri);
if (withSize) {
InputStream tmp = context.getContentResolver().openInputStream(mContentUri);
size = Apg.getLengthOfStream(tmp);
tmp.close();
}
}
} else if (mText != null || mData != null) {
byte[] bytes = null;
if (mData != null) {
bytes = mData;
} else {
bytes = mText.getBytes();
}
in = new ByteArrayInputStream(bytes);
if (withSize) {
size = bytes.length;
}
}
return new InputData(in, size);
}
}

View File

@ -16,12 +16,9 @@
package org.thialfihar.android.apg;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@ -88,6 +85,11 @@ public class DecryptActivity extends BaseActivity {
private String mOutputFilename = null;
private Uri mContentUri = null;
private byte[] mData = null;
private boolean mReturnBinary = false;
private DataSource mDataSource = null;
private DataDestination mDataDestination = null;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -186,21 +188,26 @@ public class DecryptActivity extends BaseActivity {
if (extras == null) {
extras = new Bundle();
}
String data = extras.getString(Apg.EXTRA_TEXT);
if (data != null) {
Matcher matcher = Apg.PGP_MESSAGE.matcher(data);
mData = extras.getByteArray(Apg.EXTRA_DATA);
String textData = null;
if (mData == null) {
textData = extras.getString(Apg.EXTRA_TEXT);
}
if (textData != null) {
Matcher matcher = Apg.PGP_MESSAGE.matcher(textData);
if (matcher.matches()) {
data = matcher.group(1);
textData = matcher.group(1);
// replace non breakable spaces
data = data.replaceAll("\\xa0", " ");
mMessage.setText(data);
textData = textData.replaceAll("\\xa0", " ");
mMessage.setText(textData);
} else {
matcher = Apg.PGP_SIGNED_MESSAGE.matcher(data);
matcher = Apg.PGP_SIGNED_MESSAGE.matcher(textData);
if (matcher.matches()) {
data = matcher.group(1);
textData = matcher.group(1);
// replace non breakable spaces
data = data.replaceAll("\\xa0", " ");
mMessage.setText(data);
textData = textData.replaceAll("\\xa0", " ");
mMessage.setText(textData);
mDecryptButton.setText(R.string.btn_verify);
}
}
@ -208,15 +215,12 @@ public class DecryptActivity extends BaseActivity {
mReplyTo = extras.getString(Apg.EXTRA_REPLY_TO);
mSubject = extras.getString(Apg.EXTRA_SUBJECT);
} else if (Apg.Intent.DECRYPT_FILE.equals(mIntent.getAction())) {
if ("file".equals(mIntent.getScheme())) {
mInputFilename = mIntent.getDataString().replace("file://", "");
mFilename.setText(mInputFilename);
guessOutputFilename();
} else if ("content".equals(mIntent.getScheme())) {
mInputFilename = mIntent.getDataString();
if ("file".equals(mIntent.getScheme())) {
mInputFilename = mInputFilename.substring(6);
}
mFilename.setText(mInputFilename);
guessOutputFilename();
}
mSource.setInAnimation(null);
mSource.setOutAnimation(null);
while (mSource.getCurrentView().getId() != R.id.sourceFile) {
@ -224,11 +228,15 @@ public class DecryptActivity extends BaseActivity {
}
} else if (Apg.Intent.DECRYPT_AND_RETURN.equals(mIntent.getAction())) {
mContentUri = mIntent.getData();
if (mContentUri == null) {
Bundle extras = mIntent.getExtras();
if (extras == null) {
extras = new Bundle();
}
mReturnBinary = extras.getBoolean(Apg.EXTRA_BINARY, false);
if (mContentUri == null) {
mData = extras.getByteArray(Apg.EXTRA_DATA);
String data = extras.getString(Apg.EXTRA_TEXT);
if (data != null) {
Matcher matcher = Apg.PGP_MESSAGE.matcher(data);
@ -397,19 +405,9 @@ public class DecryptActivity extends BaseActivity {
// else treat it as an decrypted message/file
mSignedOnly = false;
String error = null;
fillDataSource();
try {
InputStream in;
if (mContentUri != null) {
in = getContentResolver().openInputStream(mContentUri);
} else if (mDecryptTarget == Id.target.file) {
if (mInputFilename.startsWith("file")) {
in = new FileInputStream(mInputFilename);
} else {
in = getContentResolver().openInputStream(Uri.parse(mInputFilename));
}
} else {
in = new ByteArrayInputStream(mMessage.getText().toString().getBytes());
}
InputData in = mDataSource.getInputData(this, false);
try {
setSecretKeyId(Apg.getDecryptionKeyId(this, in));
if (getSecretKeyId() == Id.key.none) {
@ -418,19 +416,7 @@ public class DecryptActivity extends BaseActivity {
mAssumeSymmetricEncryption = false;
} catch (Apg.NoAsymmetricEncryptionException e) {
setSecretKeyId(Id.key.symmetric);
// look at the file/message again to check whether there's
// symmetric encryption data in there
if (mContentUri != null) {
in = getContentResolver().openInputStream(mContentUri);
} else if (mDecryptTarget == Id.target.file) {
if (mInputFilename.startsWith("file")) {
in = new FileInputStream(mInputFilename);
} else {
in = getContentResolver().openInputStream(Uri.parse(mInputFilename));
}
} else {
in = new ByteArrayInputStream(mMessage.getText().toString().getBytes());
}
in = mDataSource.getInputData(this, false);
if (!Apg.hasSymmetricEncryption(this, in)) {
throw new Apg.GeneralException(getString(R.string.error_noKnownEncryptionFound));
}
@ -500,61 +486,33 @@ public class DecryptActivity extends BaseActivity {
Bundle data = new Bundle();
Message msg = new Message();
fillDataSource();
fillDataDestination();
try {
PositionAwareInputStream in = null;
OutputStream out = null;
String randomString = null;
long size = 0;
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")) {
size = Apg.getLengthOfStream(getContentResolver().openInputStream(Uri.parse(mInputFilename)));
in = new PositionAwareInputStream(
getContentResolver().openInputStream(Uri.parse(mInputFilename)));
} else {
in = new PositionAwareInputStream(new FileInputStream(mInputFilename));
File file = new File(mInputFilename);
size = file.length();
}
out = new FileOutputStream(mOutputFilename);
}
InputData in = mDataSource.getInputData(this, true);
OutputStream out = mDataDestination.getOutputStream(this);
if (mSignedOnly) {
data = Apg.verifyText(this, in, out, this);
} else {
data = Apg.decrypt(this, in, out, size, Apg.getCachedPassPhrase(getSecretKeyId()),
data = Apg.decrypt(this, in, out, Apg.getCachedPassPhrase(getSecretKeyId()),
this, mAssumeSymmetricEncryption);
}
out.close();
if (randomString != null) {
data.putString(Apg.EXTRA_RESULT_URI, "content://" + DataProvider.AUTHORITY + "/data/" + randomString);
if (mDataDestination.getStreamFilename() != null) {
data.putString(Apg.EXTRA_RESULT_URI, "content://" + DataProvider.AUTHORITY +
"/data/" + mDataDestination.getStreamFilename());
} else if (mDecryptTarget == Id.target.message) {
if (mReturnBinary) {
data.putByteArray(Apg.EXTRA_DECRYPTED_DATA,
((ByteArrayOutputStream) out).toByteArray());
} else {
data.putString(Apg.EXTRA_DECRYPTED_MESSAGE,
new String(((ByteArrayOutputStream) out).toByteArray()));
}
}
} catch (PGPException e) {
error = "" + e;
} catch (IOException e) {
@ -727,4 +685,31 @@ public class DecryptActivity extends BaseActivity {
return super.onCreateDialog(id);
}
protected void fillDataSource() {
mDataSource = new DataSource();
if (mContentUri != null) {
mDataSource.setUri(mContentUri);
} else if (mDecryptTarget == Id.target.file) {
mDataSource.setUri(mInputFilename);
} else {
if (mData != null) {
mDataSource.setData(mData);
} else {
mDataSource.setText(mMessage.getText().toString());
}
}
}
protected void fillDataDestination() {
mDataDestination = new DataDestination();
if (mContentUri != null) {
mDataDestination.setMode(Id.mode.stream);
} else if (mDecryptTarget == Id.target.file) {
mDataDestination.setFilename(mOutputFilename);
mDataDestination.setMode(Id.mode.file);
} else {
mDataDestination.setMode(Id.mode.byte_array);
}
}
}

View File

@ -16,13 +16,9 @@
package org.thialfihar.android.apg;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
@ -34,8 +30,6 @@ import org.bouncycastle2.openpgp.PGPPublicKey;
import org.bouncycastle2.openpgp.PGPPublicKeyRing;
import org.bouncycastle2.openpgp.PGPSecretKey;
import org.bouncycastle2.openpgp.PGPSecretKeyRing;
import org.bouncycastle2.util.Strings;
import org.thialfihar.android.apg.Apg.GeneralException;
import org.thialfihar.android.apg.utils.Choice;
import android.app.Dialog;
@ -43,7 +37,6 @@ import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Message;
import android.text.ClipboardManager;
import android.view.View;
@ -100,6 +93,14 @@ public class EncryptActivity extends BaseActivity {
private String mInputFilename = null;
private String mOutputFilename = null;
private boolean mAsciiArmourDemand = false;
private boolean mOverrideAsciiArmour = false;
private Uri mContentUri = null;
private byte[] mData = null;
private DataSource mDataSource = null;
private DataDestination mDataDestination = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -271,6 +272,7 @@ public class EncryptActivity extends BaseActivity {
if (Apg.Intent.ENCRYPT.equals(mIntent.getAction()) ||
Apg.Intent.ENCRYPT_FILE.equals(mIntent.getAction()) ||
Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction())) {
mContentUri = mIntent.getData();
Bundle extras = mIntent.getExtras();
if (extras == null) {
extras = new Bundle();
@ -280,7 +282,17 @@ public class EncryptActivity extends BaseActivity {
mReturnResult = true;
}
String data = extras.getString(Apg.EXTRA_TEXT);
if (extras.containsKey(Apg.EXTRA_ASCII_ARMOUR)) {
mAsciiArmourDemand = extras.getBoolean(Apg.EXTRA_ASCII_ARMOUR, true);
mOverrideAsciiArmour = true;
mAsciiArmour.setChecked(mAsciiArmourDemand);
}
mData = extras.getByteArray(Apg.EXTRA_DATA);
String textData = null;
if (mData == null) {
textData = extras.getString(Apg.EXTRA_TEXT);
}
mSendTo = extras.getString(Apg.EXTRA_SEND_TO);
mSubject = extras.getString(Apg.EXTRA_SUBJECT);
long signatureKeyId = extras.getLong(Apg.EXTRA_SIGNATURE_KEY_ID);
@ -327,8 +339,8 @@ public class EncryptActivity extends BaseActivity {
if (Apg.Intent.ENCRYPT.equals(mIntent.getAction()) ||
Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction())) {
if (data != null) {
mMessage.setText(data);
if (textData != null) {
mMessage.setText(textData);
}
mSource.setInAnimation(null);
mSource.setOutAnimation(null);
@ -548,11 +560,11 @@ public class EncryptActivity extends BaseActivity {
String error = null;
Bundle data = new Bundle();
Message msg = new Message();
fillDataSource();
fillDataDestination();
try {
InputStream in;
InputData in;
OutputStream out;
long size;
boolean useAsciiArmour = true;
long encryptionKeyIds[] = null;
long signatureKeyId = 0;
@ -571,65 +583,28 @@ public class EncryptActivity extends BaseActivity {
signOnly = (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0);
}
// streams
in = mDataSource.getInputData(this, true);
out = mDataDestination.getOutputStream(this);
if (mEncryptTarget == Id.target.file) {
if (mInputFilename.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath()) ||
mOutputFilename.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
throw new GeneralException(getString(R.string.error_externalStorageNotReady));
}
}
if (mInputFilename.startsWith("content")) {
in = getContentResolver().openInputStream(Uri.parse(mInputFilename));
size = 0;
long n = 0;
byte dummy[] = new byte[0x10000];
while ((n = in.read(dummy)) > 0) {
size += n;
}
in = getContentResolver().openInputStream(Uri.parse(mInputFilename));
} else {
in = new FileInputStream(mInputFilename);
File file = new File(mInputFilename);
size = file.length();
}
out = new FileOutputStream(mOutputFilename);
useAsciiArmour = mAsciiArmour.isChecked();
compressionId = ((Choice) mFileCompression.getSelectedItem()).getId();
} else {
String message = mMessage.getText().toString();
if (signOnly && !mReturnResult) {
// fix the message a bit, trailing spaces and newlines break stuff,
// because GMail sends as HTML and such things fuck up the signature,
// TODO: things like "<" and ">" also fuck up the signature
message = message.replaceAll(" +\n", "\n");
message = message.replaceAll("\n\n+", "\n\n");
message = message.replaceFirst("^\n+", "");
// make sure there'll be exactly one newline at the end
message = message.replaceFirst("\n*$", "\n");
}
if (signOnly && !message.endsWith("\n")) {
message += '\n';
}
byte[] byteData = Strings.toUTF8ByteArray(message);
in = new ByteArrayInputStream(byteData);
out = new ByteArrayOutputStream();
size = byteData.length;
useAsciiArmour = true;
compressionId = mPreferences.getDefaultMessageCompression();
}
if (mOverrideAsciiArmour) {
useAsciiArmour = mAsciiArmourDemand;
}
if (signOnly) {
Apg.signText(this, in, out, getSecretKeyId(),
Apg.getCachedPassPhrase(getSecretKeyId()),
mPreferences.getDefaultHashAlgorithm(), this);
} else {
Apg.encrypt(this, in, out, size, useAsciiArmour,
Apg.encrypt(this, in, out, useAsciiArmour,
encryptionKeyIds, signatureKeyId,
Apg.getCachedPassPhrase(signatureKeyId), this,
mPreferences.getDefaultEncryptionAlgorithm(),
@ -639,8 +614,13 @@ public class EncryptActivity extends BaseActivity {
out.close();
if (mEncryptTarget != Id.target.file) {
if (useAsciiArmour) {
data.putString(Apg.EXTRA_ENCRYPTED_MESSAGE,
new String(((ByteArrayOutputStream)out).toByteArray()));
} else {
data.putByteArray(Apg.EXTRA_ENCRYPTED_DATA,
((ByteArrayOutputStream)out).toByteArray());
}
}
} catch (IOException e) {
error = "" + e;
@ -889,4 +869,31 @@ public class EncryptActivity extends BaseActivity {
return super.onCreateDialog(id);
}
protected void fillDataSource() {
mDataSource = new DataSource();
if (mContentUri != null) {
mDataSource.setUri(mContentUri);
} else if (mEncryptTarget == Id.target.file) {
mDataSource.setUri(mInputFilename);
} else {
if (mData != null) {
mDataSource.setData(mData);
} else {
mDataSource.setText(mMessage.getText().toString());
}
}
}
protected void fillDataDestination() {
mDataDestination = new DataDestination();
if (mContentUri != null) {
mDataDestination.setMode(Id.mode.stream);
} else if (mEncryptTarget == Id.target.file) {
mDataDestination.setFilename(mOutputFilename);
mDataDestination.setMode(Id.mode.file);
} else {
mDataDestination.setMode(Id.mode.byte_array);
}
}
}

View File

@ -14,11 +14,11 @@ import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class GeneralActivity extends BaseActivity {
private Intent mIntent;

View File

@ -135,6 +135,13 @@ public final class Id {
public static final int message = 0x21070004;
}
public static final class mode {
public static final int undefined = 0x21070001;
public static final int byte_array = 0x21070002;
public static final int file = 0x21070003;
public static final int stream = 0x21070004;
}
public static final class key {
public static final int none = 0;
public static final int symmetric = -1;

View File

@ -0,0 +1,25 @@
package org.thialfihar.android.apg;
import java.io.InputStream;
public class InputData {
private PositionAwareInputStream mInputStream;
private long mSize;
InputData(InputStream inputStream, long size) {
mInputStream = new PositionAwareInputStream(inputStream);
mSize = size;
}
public InputStream getInputStream() {
return mInputStream;
}
public long getSize() {
return mSize;
}
public long getStreamPosition() {
return mInputStream.position();
}
}

View File

@ -48,15 +48,15 @@ import android.os.Message;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
public class KeyListActivity extends BaseActivity {
protected ExpandableListView mList;
@ -328,7 +328,7 @@ public class KeyListActivity extends BaseActivity {
}
if (mTask == Id.task.import_keys) {
data = Apg.importKeyRings(this, mKeyType, importInputStream, size, this);
data = Apg.importKeyRings(this, mKeyType, new InputData(importInputStream, size), this);
} else {
Vector<Integer> keyRingIds = new Vector<Integer>();
if (mSelectedItem == -1) {

View File

@ -30,11 +30,11 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
public class MailListActivity extends ListActivity {
LayoutInflater mInflater = null;

View File

@ -29,21 +29,21 @@ import android.database.SQLException;
import android.net.Uri;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class MainActivity extends BaseActivity {
private ListView mAccounts = null;

View File

@ -18,7 +18,6 @@ package org.thialfihar.android.apg;
import org.bouncycastle2.bcpg.HashAlgorithmTags;
import org.bouncycastle2.openpgp.PGPEncryptedData;
import org.thialfihar.android.apg.utils.Choice;
import android.os.Bundle;
import android.preference.CheckBoxPreference;

View File

@ -18,9 +18,9 @@ package org.thialfihar.android.apg;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ExpandableListView;
public class PublicKeyListActivity extends KeyListActivity {

View File

@ -20,10 +20,10 @@ import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ExpandableListView.OnChildClickListener;

View File

@ -23,10 +23,10 @@ import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
public class SelectSecretKeyListActivity extends BaseActivity {
protected ListView mList;