diff --git a/res/layout/encrypt_file.xml b/res/layout/encrypt_file.xml index 8a2b9665b..0c388fbe7 100644 --- a/res/layout/encrypt_file.xml +++ b/res/layout/encrypt_file.xml @@ -49,6 +49,12 @@ + + + - - - + + + android:fillViewport="true"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/res/values/strings.xml b/res/values/strings.xml index f64258e0a..5ad12d0ff 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -83,5 +83,7 @@ Save As... Save + ASCII armour + diff --git a/src/org/thialfihar/android/apg/Apg.java b/src/org/thialfihar/android/apg/Apg.java index 80865ada3..a5daca0cb 100644 --- a/src/org/thialfihar/android/apg/Apg.java +++ b/src/org/thialfihar/android/apg/Apg.java @@ -1147,11 +1147,17 @@ public class Apg { boolean armored, long encryptionKeyIds[], long signatureKeyId, String signaturePassPhrase, - ProgressDialogUpdater progress) + ProgressDialogUpdater progress, + int symmetricAlgorithm, + String passPhrase) throws IOException, GeneralException, PGPException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException { Security.addProvider(new BouncyCastleProvider()); + if (encryptionKeyIds == null) { + encryptionKeyIds = new long[0]; + } + ArmoredOutputStream armorOut = null; OutputStream out = null; OutputStream encryptOut = null; @@ -1166,8 +1172,8 @@ public class Apg { PGPSecretKeyRing signingKeyRing = null; PGPPrivateKey signaturePrivateKey = null; - if (encryptionKeyIds == null || encryptionKeyIds.length == 0) { - throw new GeneralException("no encryption key(s) given"); + if (encryptionKeyIds.length == 0 && passPhrase == null) { + throw new GeneralException("no encryption key(s) or pass phrase given"); } if (signatureKeyId != 0) { @@ -1199,9 +1205,13 @@ public class Apg { progress.setProgress("preparing streams...", 20, 100); // encryptFile and compress input file content PGPEncryptedDataGenerator cPk = - new PGPEncryptedDataGenerator(PGPEncryptedData.AES_256, true, new SecureRandom(), + new PGPEncryptedDataGenerator(symmetricAlgorithm, true, new SecureRandom(), new BouncyCastleProvider()); + if (encryptionKeyIds.length == 0) { + // symmetric encryption + cPk.addMethod(passPhrase.toCharArray()); + } for (int i = 0; i < encryptionKeyIds.length; ++i) { PGPPublicKey key = getEncryptPublicKey(encryptionKeyIds[i]); if (key != null) { diff --git a/src/org/thialfihar/android/apg/EncryptFileActivity.java b/src/org/thialfihar/android/apg/EncryptFileActivity.java index d32f1ccf6..ce2cf9031 100644 --- a/src/org/thialfihar/android/apg/EncryptFileActivity.java +++ b/src/org/thialfihar/android/apg/EncryptFileActivity.java @@ -31,12 +31,14 @@ import java.util.Collections; import java.util.Vector; import org.bouncycastle2.bcpg.HashAlgorithmTags; +import org.bouncycastle2.openpgp.PGPEncryptedData; import org.bouncycastle2.openpgp.PGPException; import org.bouncycastle2.openpgp.PGPPublicKeyRing; import org.bouncycastle2.openpgp.PGPSecretKey; import org.bouncycastle2.openpgp.PGPSecretKeyRing; import org.openintents.intents.FileManager; import org.thialfihar.android.apg.Apg.GeneralException; +import org.thialfihar.android.apg.utils.Choice; import android.app.Dialog; import android.content.ActivityNotFoundException; @@ -47,11 +49,13 @@ import android.os.Environment; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; +import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageButton; import android.widget.ListView; +import android.widget.Spinner; import android.widget.TabHost; import android.widget.TextView; import android.widget.Toast; @@ -68,17 +72,24 @@ public class EncryptFileActivity extends BaseActivity { private TextView mMainUserId = null; private TextView mMainUserIdRest = null; private ListView mPublicKeyList = null; + private Spinner mAlgorithm = null; + private EditText mPassPhrase = null; + private EditText mPassPhraseAgain = null; + private Button mAsciiArmour = null; private Button mEncryptButton = null; private long mEncryptionKeyIds[] = null; private String mInputFilename = null; private String mOutputFilename = null; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.encrypt_file); + mAsciiArmour = (CheckBox) findViewById(R.id.ascii_armour); + mTabHost = (TabHost) findViewById(R.id.tab_host); mTabHost.setup(); @@ -96,6 +107,8 @@ public class EncryptFileActivity extends BaseActivity { mTabHost.setCurrentTab(0); + // asymmetric tab + Vector keyRings = (Vector) Apg.getPublicKeyRings().clone(); Collections.sort(keyRings, new Apg.PublicKeySorter()); @@ -130,6 +143,34 @@ public class EncryptFileActivity extends BaseActivity { } }); + // symmetric tab + + mAlgorithm = (Spinner) findViewById(R.id.algorithm); + Choice choices[] = { + new Choice(PGPEncryptedData.AES_128, "AES 128"), + new Choice(PGPEncryptedData.AES_192, "AES 192"), + new Choice(PGPEncryptedData.AES_256, "AES 256"), + new Choice(PGPEncryptedData.BLOWFISH, "Blowfish"), + new Choice(PGPEncryptedData.TWOFISH, "Twofish"), + new Choice(PGPEncryptedData.CAST5, "CAST5"), + new Choice(PGPEncryptedData.DES, "DES"), + new Choice(PGPEncryptedData.TRIPLE_DES, "Triple DES"), + new Choice(PGPEncryptedData.IDEA, "IDEA"), + }; + ArrayAdapter adapter = + new ArrayAdapter(this, android.R.layout.simple_spinner_item, choices); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + mAlgorithm.setAdapter(adapter); + for (int i = 0; i < choices.length; ++i) { + if (choices[i].getId() == PGPEncryptedData.AES_256) { + mAlgorithm.setSelection(i); + break; + } + } + + mPassPhrase = (EditText) findViewById(R.id.pass_phrase); + mPassPhraseAgain = (EditText) findViewById(R.id.pass_phrase_again); + mEncryptButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -232,7 +273,20 @@ public class EncryptFileActivity extends BaseActivity { return; } } else { + // symmetric encryption + String passPhrase = mPassPhrase.getText().toString(); + String passPhraseAgain = mPassPhraseAgain.getText().toString(); + if (!passPhrase.equals(passPhraseAgain)) { + Toast.makeText(this, "Pass phrases don't match.", + Toast.LENGTH_SHORT).show(); + return; + } + if (passPhrase.length() == 0) { + Toast.makeText(this, "Enter a pass phrase.", + Toast.LENGTH_SHORT).show(); + return; + } } askForOutputFilename(); @@ -274,14 +328,16 @@ public class EncryptFileActivity extends BaseActivity { boolean encryptIt = mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0; if (encryptIt) { - Apg.encrypt(in, out, true, mEncryptionKeyIds, getSecretKeyId(), - Apg.getPassPhrase(), this); - } else { - Apg.signText(in, out, getSecretKeyId(), - Apg.getPassPhrase(), HashAlgorithmTags.SHA256, this); + Apg.encrypt(in, out, mAsciiArmour.isSelected(), + mEncryptionKeyIds, getSecretKeyId(), + Apg.getPassPhrase(), this, + PGPEncryptedData.AES_256, null); } } else { - + Apg.encrypt(in, out, mAsciiArmour.isSelected(), + null, 0, null, this, + ((Choice) mAlgorithm.getSelectedItem()).getId(), + mPassPhrase.getText().toString()); } out.close(); diff --git a/src/org/thialfihar/android/apg/EncryptMessageActivity.java b/src/org/thialfihar/android/apg/EncryptMessageActivity.java index 4b808ba85..e09ae9ade 100644 --- a/src/org/thialfihar/android/apg/EncryptMessageActivity.java +++ b/src/org/thialfihar/android/apg/EncryptMessageActivity.java @@ -25,6 +25,7 @@ import java.security.SignatureException; import java.util.Vector; import org.bouncycastle2.bcpg.HashAlgorithmTags; +import org.bouncycastle2.openpgp.PGPEncryptedData; import org.bouncycastle2.openpgp.PGPException; import org.bouncycastle2.openpgp.PGPPublicKey; import org.bouncycastle2.openpgp.PGPPublicKeyRing; @@ -200,7 +201,8 @@ public class EncryptMessageActivity extends BaseActivity { if (encryptIt) { Apg.encrypt(in, out, true, mEncryptionKeyIds, getSecretKeyId(), - Apg.getPassPhrase(), this); + Apg.getPassPhrase(), this, + PGPEncryptedData.AES_256, null); } else { Apg.signText(in, out, getSecretKeyId(), Apg.getPassPhrase(), HashAlgorithmTags.SHA256, this); diff --git a/src/org/thialfihar/android/apg/ui/widget/KeyEditor.java b/src/org/thialfihar/android/apg/ui/widget/KeyEditor.java index 15d6eb3ea..2ec1dcc4d 100644 --- a/src/org/thialfihar/android/apg/ui/widget/KeyEditor.java +++ b/src/org/thialfihar/android/apg/ui/widget/KeyEditor.java @@ -26,7 +26,6 @@ import org.bouncycastle2.openpgp.PGPSecretKey; import org.thialfihar.android.apg.Apg; import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.R; -import org.thialfihar.android.apg.R.id; import org.thialfihar.android.apg.utils.Choice; import android.app.DatePickerDialog;